因为RecyclerView在计算layout的时候不允许你更新Adapter内容。
这些notify去更新adapter的内容时,如果RcyclerView正在isComputingLayout,就会报此错误;
image.png
在recyclerView中的实现
image.png
在assertNotInLayoutOrScroll方法中,如果isComputingLayout为true,就会报错
image.png
iscomputingLayout方法如下,是通过mLayoutOrScrollCounter成员变量统计正在layout或scroll的item的数量
public boolean isComputingLayout() {
return mLayoutOrScrollCounter > 0;
}
上面是异常路径,以下分析导致这个异常的原因
recyclerview对应一个adapter,当adapter中的数据发生改变时,必须通过notify方法通知recyclerview
List<TimelineItemResp> buyList = data.getPageData();
if (pageNo == 1) {
purchaseWorks.clear();
List<DataTabResp> tabList = data.getTabList();
getUI().updateFilterData(tabList, data.getBuyCount());
}
if (buyList != null ) {
if ( buyList.size() <= 0) {
getUI().setLoadMoreEnable(false);
} else {
getUI().setLoadMoreEnable(true);
purchaseWorks.addAll(buyList);
getUI().updateWorkList(purchaseWorks);
pageNo++;
}
}
setLoadMoreEnable(false);这个方法中由于业务逻辑做了一个notifyItemChanged(itemCount - 1);
updateWorkList(purchaseWorks);方法是直接给adapter。addAll,如下
网络请求的数据,传的是对象的地址值
public void addAll(List<T> mList) {
mDatas = mList;
notifyDataSetChanged();
}
网络请求的数据list没有数据时,adapter中的dataList会被clear,然后走notifyItemChanged(-1);,数据改变,notify错误,如果不及时纠正,就会报此错误,
getAdapter().getDataList().clear();
getAdapter().notifyItemChanged(0);
getAdapter().notifyDataSetChanged();
清除数据后,notifyitem错误,然后及时调用notifyDataSetChanged纠正错误,就不会出错。
如果notifyitem错误后,再继续notifyitem,就会报错
如果notifyitem错误后,adapter中的datalist又发生改变,notifyDataSetChanged也会报错。
结论:adapter中的datalist数据发生改变,notify错误,没有及时纠正,或者数据又改变,也会报此错,所以数据改变要notify正确,比如position正确,notifyitem时一定要保证position是正确的(pos有效,不越界),notifyDataSetChanged没有这问题
网友评论