再看IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter

IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter这个异常在之前就已经遇到过了,是发生在数据更新的时候。当时的解决办法是重写相应的LayoutManager的onLayoutChildren方法解决的,解决代码如下:

public class WrapContentLinearLayoutManager extends LinearLayoutManager {  
    public WrapContentLinearLayoutManager(Context context) {  
        super(context);  
    }  
  
    public WrapContentLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {  
        super(context, orientation, reverseLayout);  
    }  
  
    public WrapContentLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {  
        super(context, attrs, defStyleAttr, defStyleRes);  
    }  
  
    @Override  
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {  
        try {  
            super.onLayoutChildren(recycler, state);  
        } catch (IndexOutOfBoundsException e) {  
            e.printStackTrace();  
        }  
    }  
}  

今天又遇到了这个问题,发现是在adapter绑定的mData在清除最后一个数据之前的所有数据,然后再添加一组数据在最后一个数据之前,再调用notifyItemRangeInserted的时候出现的,话说的可能不是很清楚,用代码解释,如下:

public void set(List newData){
    Object lastObject = mCollection.get(mCollection.size() - 1);
    mData.clear();
    mData.add(0, lastObject);
    notifyItemInserted(position);
    mData.addAll(0, newData);
    notifyItemRangeInserted(position, newData.size());//不要问我为什么要先mData.add(0, lastObject),再mData.addAll(0, newData);而不是先mData.addAll(newData),再mData.add(lastObject),剧情需要
}

上述代码执行的时候就抛出了该异常,网上也有很多人出现该问题:

Paste_Image.png

https://issuetracker.google.com/issues/37030377 #7

其实归根结底,还是adapter的item和数据源data不一致造成的!!!

解决办法如最上面说的重写相应LayoutManager的onLayoutChildren,在里面捕获异常即可,但是有人不提倡这么做:
https://issuetracker.google.com/issues/37030377 #12

再看IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter_第1张图片
Paste_Image.png

大意是这样做会让RecyclerView处于不和逻辑的状态,有可能让RV崩溃,因为它失去了它的状态。

那还有什么解决办法呢?其实只要保持adapter的item和数据源data一致不就行了?!

正如之前在示例代码中所说的,

再看IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter_第2张图片
Paste_Image.png

我们可以先调用mData.addAll(newData),再调用mData.add(lastObject),最后再调用notifyxxx即可。

这时你可能会用我的“剧情需要”来问我:万一某些情况就是需要先移出mData最后一项之前的数据,在添加新数据到mData最后一项之前呢?

于是我又屁颠屁颠的去google了,嘿嘿嘿,google果然是一个伟大的发明:

再看IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter_第3张图片
Paste_Image.png

http://stackoverflow.com/questions/31759171/recyclerview-and-java-lang-indexoutofboundsexception-inconsistency-detected-in

你,试了吗?

你可能感兴趣的:(再看IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter)