youlookwhat / ByRecyclerView

🔥 RecyclerView 下拉刷新、上拉松手/自动加载更多、item点击/长按、item局部刷新、头布局/尾布局/状态布局、万能分割线、Skeleton骨架图、极简adapter、嵌套滑动置顶
https://youlookwhat.github.io/ByRecyclerView
Apache License 2.0
798 stars 139 forks source link

有个bug #19

Closed renhuan closed 3 years ago

renhuan commented 3 years ago

使用 recycleview.setStateView(R.layout.statu_loading) 搭配 DiffUtil 会报错 java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionSimpleViewHolder

youlookwhat commented 3 years ago

setStateView 可以理解为一个headerView,不知道你使用addHeaderView是否会有问题。在DiffUtil里需要使用正确的Position,应该是需要减掉 recyclerView.getCustomTopItemViewCount()。你减去这个再试试

youlookwhat commented 3 years ago

使用addHeaderView我试了DiffUtil没发现问题,如果你试了后还有问题的话,我改改

renhuan commented 3 years ago

setStateView 可以理解为一个headerView,不知道你使用addHeaderView是否会有问题。在DiffUtil里需要使用正确的Position,应该是需要减掉 recyclerView.getCustomTopItemViewCount()。你减去这个再试试

我在DiffUtils之前 recyclerView.isStateViewEnabled = false 写了这句的,我看源码应该是把size置为0了,理论上不应该是position的问题

` /**

renhuan commented 3 years ago

setStateView 可以理解为一个headerView,不知道你使用addHeaderView是否会有问题。在DiffUtil里需要使用正确的Position,应该是需要减掉 recyclerView.getCustomTopItemViewCount()。你减去这个再试试

事实上我打印getCustomTopItemViewCount确实也为0

youlookwhat commented 3 years ago

setStateView将position=0位置为状态布局,使用的是SimpleViewHolder;然而DiffUtils时positin=0会是内容的adapter,这样会出现问题。看来如果要使用setStateView,一定要使用notifyDataSetChanged()。因为position的位置会变化,这种好像也是无解的。

有一种其他的方式可以解决,不过可能不太友好,就是StateView不设置为false,设置一个0高度的布局,这样position的位置也不会变。headerview因为不会消失,所以使用DiffUtils也没问题,如果消失了可能也会出现问题。

renhuan commented 3 years ago

setStateView将position=0位置为状态布局,使用的是SimpleViewHolder;然而DiffUtils时positin=0会是内容的adapter,这样会出现问题。看来如果要使用setStateView,一定要使用notifyDataSetChanged()。因为position的位置会变化,这种好像也是无解的。

有一种其他的方式可以解决,不过可能不太友好,就是StateView不设置为false,设置一个0高度的布局,这样position的位置也不会变。headerview因为不会消失,所以使用DiffUtils也没问题,如果消失了可能也会出现问题。

方法一是可以的 https://www.jianshu.com/p/2eca433869e9 ,谢啦,下班

renhuan commented 3 years ago

setStateView将position=0位置为状态布局,使用的是SimpleViewHolder;然而DiffUtils时positin=0会是内容的adapter,这样会出现问题。看来如果要使用setStateView,一定要使用notifyDataSetChanged()。因为position的位置会变化,这种好像也是无解的。

有一种其他的方式可以解决,不过可能不太友好,就是StateView不设置为false,设置一个0高度的布局,这样position的位置也不会变。headerview因为不会消失,所以使用DiffUtils也没问题,如果消失了可能也会出现问题。

你觉得设置为false的时候移除StateView 可不可行

youlookwhat commented 3 years ago

可以,我尝试一下👌

youlookwhat commented 3 years ago
    public void setStateViewEnabled(boolean stateViewEnabled, boolean isRemoveRefresh) {
        this.mStateViewEnabled = stateViewEnabled;
        if (isRemoveRefresh && !mStateViewEnabled) {
            if (mWrapAdapter != null) {
                mWrapAdapter.getOriginalAdapter().notifyItemRemoved(getPullHeaderSize() + getHeaderViewCount());
            }
        }
    }

加了一个这个方法,可以设置 setStateViewEnabled(false,true);试试,我这边还没测试diff的情况