RecyclerView下拉重新整理資料的一個Bug
報錯的資訊是:IndexOutOfBoundsException: Inconsistency detected. Invalid item position,但是根據錯誤日誌完全不知道是哪裡出錯。
後來經過Debug除錯一步步排查,確定了錯誤的位置所在,相關程式碼如下:
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener()
{
@Override
public void onRefresh()
{
page = 1;
clearCache();
mIsRefreshing = true;
getGankMeizi();
}
});
注意這裡的clearCache(); 重點就在這裡,使用RecyclerView加SwipeRefreshLayout的時候,如果繫結的 List 物件在更新資料之前進行了 clear,而這時使用者緊接著迅速上滑RecycleView,就會造成崩潰,而且異常不會報到你的程式碼上,屬於RecycleView的內部錯誤。原因是,當你 clear 了 list 之後,這時迅速上滑,而新資料還沒到來,導致 RecycleView 要更新載入下面的 Item 時候,找不到資料來源了,造成程式直接崩潰了.
解決方案:
很明顯,更新資料之前 clear list 是挺常見的做法,你不可能祈禱使用者這時候乖乖不動等待新資料載入完,所以根本就是不合理的。
Stack Overflow 上也有這個問題,未能夠解決:
[How to change contents of RecyclerView while scrolling] (http://stackoverflow.com/questions/26827222/how-to-change-contents-of-recyclerview-while-scrolling)
Google code 論壇上也有這個 issue,一堆跟帖,都是描述如何重現,未能夠解決:
[https://code.google.com/p/android/issues/detail?id=77846] (https://code.google.com/p/android/issues/detail?id=77846)
下邊是我的解決方案:
private void setRecycleScrollBug()
{
mRecyclerView.setOnTouchListener(new View.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
if (mIsRefreshing)
{
return true;
} else
{
return false;
}
}
});
}
這時攔截RecycleView的滑動事件,禁止使用者去手動向上滑動RecyclerView,暫時很完美的解決了這個問題,但是目前還沒找到更好的解決辦法,這個Bug目前到現在更新到
com.android.support:design:25.0.0,Google還是沒有很完美的解決這個問題。