美文网首页
再看IndexOutOfBoundsException: Inc

再看IndexOutOfBoundsException: Inc

作者: GIndoc | 来源:发表于2017-05-10 15:06 被阅读50次

    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

    Paste_Image.png

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

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

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

    Paste_Image.png

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

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

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

    Paste_Image.png

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

    你,试了吗?

    相关文章

      网友评论

          本文标题:再看IndexOutOfBoundsException: Inc

          本文链接:https://www.haomeiwen.com/subject/bwhgtxtx.html