Android中RecyclerView出現java.lang.IndexOutOfBoundsException


在RecyclerView更細數據時出現java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder錯誤時,有如下三種解決方案:

1. 自定義類繼承LinearLayoutManager的包裝類

自定義類繼承LinearLayoutManager,重寫onLayoutChildren,捕獲異常

public class WrapContentLinearLayoutManager extends LinearLayoutManager {

public WrapContentLinearLayoutManager(Context context) {
super(context);
}

@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
try {
super.onLayoutChildren(recycler, state);
} catch (IndexOutOfBoundsException e) {
Log.e("RecyclerView", e.getMessage());
}
}
}

2.保證外部數據集和內部數據集實時保持一致

在進行數據移除和數據增加時,務必要保證RecyclerView的Adapter中的數據集和移除/添加等操作后的數據集保持一致!

這里,前者是在該Adapter內部,不妨叫做內部數據集,后者是開發人員傳過給Adapter的,不妨叫外部數據集。更新RecyclerView數據時,需要保證外部數據集和內部數據集實時保持一致。

外部數據集同步到內部數據集,使用如下的方法:

  • notifyItemRangeRemoved();
  • notifyItemRangeInserted();
  • notifyItemRangeChanged();
  • notifyDataSetChanged();

這里對notifyDataSetChange()做些說明: 
使用該方法的更新內部數據集,沒有默認的動畫效果,同時更新數據的效率頁不如上面的方法,官方不推薦使用這種方式更新數據集。

public void notifyData(List<PoiItem> poiItemList) {
    if (poiItemList != null) {
        int previousSize = mPoiItems.size();
        mPoiItems.clear();
        notifyItemRangeRemoved(0, previousSize);
        mPoiItems.addAll(poiItemList);
        notifyItemRangeInserted(0, poiItemList.size());
    }
}
每次對外部數據集做改動時,主動和內部數據集做一次同步操作,動畫效果也得到了保持

3.使用notifyDataSetChanged同步外部數據集和內部數據集

使用notifyDataSetChanged同步外部數據集和內部數據集。該方法簡單,但是失去了動畫效果,並且更新數據的性能低


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM