RecyclerView快速滑動到頂部刷新瞧柔,報(bào)Inconsistency detected異常漆弄。
解決方法1:重寫LayoutManger的supportsPredictiveItemAnimations()方法,return false;(經(jīng)過本人嘗試造锅,下拉刷新的時候清空數(shù)據(jù)集合撼唾,獲取數(shù)據(jù)后使用notifyDataSetChanged()方法,下拉刷新的一瞬間快速上滑動還是可能會發(fā)生這種錯誤)
I had a (possibly) related issue - entering a new instance of an activity with a RecyclerView, but with a smaller adapter was triggering this crash for me.
RecyclerView.dispatchLayout()
can try to pull items from the scrap before calling mRecycler.clearOldPositions()
. The consequence being, is that it was pulling items from the common pool that had positions heigher than the adapter size.
Fortunately, it only does this if PredictiveAnimations are enabled, so my solution was to subclass GridLayoutManager (LinearLayoutManager has the same problem and 'fix'), and override supportsPredictiveItemAnimations()
to return false :
/** * No Predictive Animations GridLayoutManager */
private static class NpaGridLayoutManager extends GridLayoutManager {
/**
* Disable predictive animations. There is a bug in RecyclerView which causes views that * are being reloaded to pull invalid ViewHolders from the internal recycler stack if the
* adapter size has decreased since the ViewHolder was recycled.
*/
@Override
public boolean supportsPredictiveItemAnimations() {
return false;
}
public NpaGridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public NpaGridLayoutManager(Context context, int spanCount) {
super(context, spanCount);
}
public NpaGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) {
super(context, spanCount, orientation, reverseLayout);
}
}
解決方法2:不使用notifyDataSetChanged()方法更新數(shù)據(jù)哥蔚,刷新的時候使用RecyclerView 的notifyItemRangeRemoved()方法移除數(shù)據(jù)倒谷,后取到數(shù)據(jù)的時候使用notifyItemRangeInserted()方法添加數(shù)據(jù)