滑动RecyclerView时出现异常: java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item posit

RecyclerView 存在的一个明显的 bug 一直没有修复:

java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position…

重现的方法是:使用 RecyclerView 加官方下拉刷新的时候,如果绑定的 List 对象在更新数据之前进行了 clear,而这时用户紧接着迅速上滑 RV,就会造成崩溃,而且异常不会报到你的代码上,属于RV内部错误。初次猜测是,当你 clear 了 list 之后,这时迅速上滑,而新数据还没到来,导致 RV 要更新加载下面的 Item 时候,找不到数据源了,造成 crash.

但明显,更新数据之前 clear list 是挺常见的做法,你不可能祈祷用户这时候乖乖不动等待新数据加载完,所以根本就是不合理的。

就是在刷新,也就是 clear 的同时,让 RecyclerView 暂时不能够滑动,之后再允许滑动即可。代码就是在 RecyclerView 初始化的时候加上是否在刷新进而拦截手势:

mRecyclerView.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {if (mIsRefreshing) {return true;} else {return false;}}}
);

然后去改变和恢复 mIsRefreshing 这个 boolean 即可。想象中觉得如果不让用户滑动很愚蠢,但不得不这么做的时候,发现真实效果很算完美,很不错的!我想基本上使用 RecyclerView 都会遇到这个问题,所以将它整理发表出来,一起绕过这个坑吧。

 

还有一种解决办法就是,我们写一个WrapContentLinearLayoutManager去继承LinearLayoutManager,在出现问题的时候我们catch了,这样的处理方法我觉得还是可以的,具体实现如下:

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();  }  }  
}  

然后设置Recyclerview的Manager为我们自己的Manager:

mRecyclerView.setLayoutManager(new WrapContentLinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));  

如果上面两种都不行,那看看最后一个办法

解决方法:

在数据addAll之前清除数据,不能在刷新时清除数据。

或者 本来就是主线程,再次提交到主线程,这样就有一定时间差,快速滑动列表就容易崩溃

        if (msgAdapter != null) {
//            new Handler().post(new Runnable() { //todo 不要打开这个,否则快速滑动recyclerview会崩溃
//                @Override
//                public void run() {// 刷新操作msgAdapter.notifyDataSetChanged();
//                }
//            });}

 


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部