RecyclerView Bug
IndexOutOfBoundsException: Inconsistency detected. Invalid item position
之前在做萌妹纸App的时候,一位同学给我提了一个issuse,原因是使用RecycleView下拉拉取新数据的时候,同时在向上滑动RecycleView时程序就崩溃了。
Gif
GIF_20160719_085409.gif
报错截图
QQ图片20160719083816.jpg
- 我去 完全看不出到底是哪里报错了,先看下代码是怎么写的.
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener()
{
@Override
public void onRefresh()
{
page = 1;
clearCache();
mIsRefreshing = true;
getGankMeizi();
}
});
- 注意这里的clearCache(); 重点就在这里,使用 RecyclerView 加官方下拉刷新的时候,如果绑定的 List 对象在更新数据之前进行了 clear,而这时用户紧接着迅速上滑RecycleView,就会造成崩溃,而且异常不会报到你的代码上,属于RecycleView的内部错误。原因是,当你 clear 了 list 之后,这时迅速上滑,而新数据还没到来,导致 RecycleView 要更新加载下面的 Item 时候,找不到数据源了,造成程序直接崩溃了.
解决方法
但明显,更新数据之前 clear list 是挺常见的做法,你不可能祈祷用户这时候乖乖不动等待新数据加载完,所以根本就是不合理的。
Stack Overflow 上也有这个问题,未能够解决:
How to change contents of RecyclerView while scrollingGoogle code 论坛上也有这个 issue,一堆跟帖,都是描述如何重现,未能够解决:
https://code.google.com/p/android/issues/detail?id=77846这里引用了@drakeet 大神的解决方法,看代码.
private void setRecycleScrollBug()
{
mRecyclerView.setOnTouchListener(new View.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
if (mIsRefreshing)
{
return true;
} else
{
return false;
}
}
});
}
- 代码很简单,就是设置一个boolean值,下拉刷新时设为true,刷新完毕后设为false,这样下拉拉取新数据时,这时RecycleView就不能进行滑动,很完美的解决了这个问题,但是目前还没找到更好的解决办法,不过我相信有很多同学肯定也遇到了这个问题,所以在这里分享下,如果你有更好的解决方案也可在评论下告知,共同交流学习.
萌妹纸App
https://github.com/HotBitmapGG/MoeQuest