RecyclerView快速滑动到顶部刷新,报Inconsistency detected异常。
解决方法1:重写LayoutManger的supportsPredictiveItemAnimations()方法,return false;(经过本人尝试,下拉刷新的时候清空数据集合,获取数据后使用notifyDataSetChanged()方法,下拉刷新的一瞬间快速上滑动还是可能会发生这种错误)
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()方法更新数据,刷新的时候使用RecyclerView 的notifyItemRangeRemoved()方法移除数据,后取到数据的时候使用notifyItemRangeInserted()方法添加数据