后记:这篇文章写于 2015 年,文中提到的解决办法至今不失为一个好办法。但后来由于我对 RecyclerView 更深入的了解,发现这个问题是存在于 RecyclerView 和 Android UI 刷新的机制里的,它几乎很难被从根源上解决,但我也找到了更好的方案,即只要在操作数据的时候采用原子操作即可根本上避免这个问题。关于此,有机会的话,我将写另一篇详细的文章来阐述。

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

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

但明显,更新数据之前 clear list 是挺常见的做法。


好在我想到了解决这个问题的方法:

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

1
2
3
4
5
6
7
8
mRecyclerView.setOnTouchListener(
new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return mIsRefreshing;
}
}
);

然后去改变和恢复 mIsRefreshing 这个 boolean 即可。当不得不这么做的时候,发现真实效果很算完美,很不错的!