本文介紹項目中使用RecyclerView遇到的一個小坑。
異常原因:java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 10…
復(fù)現(xiàn)手法:RecyclerView使用SwipeRefreshLayout下拉刷新數(shù)據(jù),迅速上滑RecyclerView,這時新數(shù)據(jù)還沒到來,RecyclerView要加載下面的Item,又沒有數(shù)據(jù)源,就會造成崩潰,而且異常不會報到我們的代碼上,拋出RecyclerView內(nèi)部錯誤。
解決辦法:
1.下滑的同時到adapter更新數(shù)據(jù)完畢,讓RecyclerView暫時禁止滑動。
rvActivityList.setOnTouchListener(newView.OnTouchListener() {
? ?@Override
? ? public booleanonTouch(View v,MotionEvent event) {
? ? ? ? if(isDoingRefresh) {
? ? ? ? ? ?return true;
? ? ? ? }else{
? ? ? ? return false;
? ? ? ?}
? ? }
});?
//當(dāng)刷新時設(shè)置//mIsRefreshing=true;//刷新完畢后還原為false//mIsRefreshing=false;此方法用戶體驗差,極為不明智。
2.第二種方法
我們在進(jìn)行數(shù)據(jù)移除和數(shù)據(jù)增加時,務(wù)必要保證RecyclerView的Adapter中的數(shù)據(jù)集和移除/添加等操作后的數(shù)據(jù)集保持一致!
外部數(shù)據(jù)集同步到內(nèi)部數(shù)據(jù)集,使用如下的方法:
notifyItemRangeRemoved();
notifyItemRangeInserted();
notifyItemRangeChanged();
notifyDataSetChanged();
使用notifyDataSetChange()方法更新內(nèi)部數(shù)據(jù)集,沒有默認(rèn)的動畫效果,同時更新數(shù)據(jù)的效率頁不如上面的方法,官方不推薦使用這種方式更新數(shù)據(jù)集,個人認(rèn)為使用這個還不如使用ListView。
mLeaveList.clear();
mAdapter.notifyItemRangeRemoved(0,preListSize);//通知RecyclerView移除數(shù)據(jù)集
mLeaveList.addAll(result);
mAdapter.notifyItemRangeInserted(0,mLeaveList.size());//更新RecyclerView數(shù)據(jù)集
每次對List進(jìn)行操作時,通知到Adapter數(shù)據(jù)已改變。