Cannot call this method while RecyclerView is computing a layout or scrolling
chowaikong opened this issue · 17 comments
我使用 android.support.v4.widget.SwipeRefreshLayout
来对 RecyclerView 下拉刷新数据,在完成刷新后就立刻执行了 LoadMoreWrapper 里面的加载更多,因为我 setListener 了。
我也看到 README 说 LoadMoreWrapper 在数据不足一整个屏幕的时候也会触发加载数据,所以会触发 RecyclerView 这个异常 Cannot call this method while RecyclerView is computing a layout or scrolling
, 也就是 RecyclerView 在 onLayout 时 调用了 notify 相关的方法。
不知道作者有没有遇到过这个问题?我在你的 demo 里面操作了同样的步骤,但是奇怪的是并没有触发这个异常,在我的项目里面却触发了,所以想请教一下解决办法。
我添加数据后是用的 notifyItemRangeInserted
,不是 notifyDataSetChanged
。
在还没下拉之前,数据是否足够铺满屏幕?下拉刷新后是使用的 notifyItemRangeInserted
,数据还是不足整个屏幕?
主要信息是:Cannot call this method while RecyclerView is computing a layout or scrolling
那就开始来排错吧,应该不是 scrolling 了,因为 LoadMoreWrapper 加载更多有判断:
LoadMoreAdapter.java#L204
if (newState == RecyclerView.SCROLL_STATE_IDLE && mOnLoadMoreListener != null) {
//....
mOnLoadMoreListener.onLoadMore(mEnabled);
}
那可以使用 recyclerView.isComputingLayout()
判断下是否正在计算 layout 。
你可以检查一下是否在下拉刷新 notify 过程中又进行了 notify 。
如果还没有解决,我们再来排查
是足够铺满屏幕的。
添加了 recyclerView.isComputingLayout()
会导致刷新后直接滑到底部显示 loading,而实际上并没有加载,只是显示 loading 而已。
另外我发现,使用 notifyItemRangeChanged
通知更新就没有以上的问题了,要看看这两个 notify 代码实现上的差别了。
那麻烦你 debug 一下 LoadMoreAdapter.java#L388
第388行,看是否进入到这里之后由于调用了 notifyItemRemoved(position)
导致的
没有修改 mShouldRemove
的值,或进入 LoadMoreAdapter.this.notifyItemRemoved(position)
如果没有进入那就排除了这个可能性,那么可以在下拉之后,在 onLoadMore 里尝试如下方法
recyclerView.post(new Runnable() {
@Override
public void run() {
// notifyItemRangeInserted()
}
});
这样会触发这个异常:
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder
要怎样复现你说这个错误,或者你是否能提供个 demo 呢?如果可以的话,可以加我 QQ353932158
已加Q
多谢反馈
这个问题我也遇到了,怎么解决的,搞了一天了/(ㄒoㄒ)/~~
@hanqingkai 请先升级到最新版本,触发 Cannot call this method while RecyclerView is computing a layout or scrolling
的根本原因说的很清楚,在 rv 还在 computing a layout 或 scrolling 的时候不应该再次调用 notify ,通常会造成这个原因是上次 notify 后,rv 还没有刷新完毕然后又进行了再次 notify,比如数据刷新 loadmore 没有延时操作,或者连续触发 loadmore (notify)等,这些原因比较常见。
如果是触发 java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder
,这个就慢慢 debug,在哪个环节出现了问题。
我搞了一天加载更多,遇到了这个问题,发现需要加个延时操作,所以加载更多的时候一定要调网络接口,不能直接add数据后就调用adapter的更新数据方法
@hanqingkai 可能是你的数据同步问题,之前我使用这个库写测试数据就是直接在 listener 里面 add 数据然后 notify 的,没问题。
@hanqingkai 请先升级到最新版本,触发
Cannot call this method while RecyclerView is computing a layout or scrolling
的根本原因说的很清楚,在 rv 还在 computing a layout 或 scrolling 的时候不应该再次调用 notify ,通常会造成这个原因是上次 notify 后,rv 还没有刷新完毕然后又进行了再次 notify,比如数据刷新 loadmore 没有延时操作,或者连续触发 loadmore (notify)等,这些原因比较常见。
如果是触发java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder
,这个就慢慢 debug,在哪个环节出现了问题。
大佬,这个问题一般都怎么debug?线上有报错,但是却复现不出来
@galaxylei 在你改动数据源的地方和刷新的地方加断点试试