RecyclerView notifyItemInserted IllegalStateException

我正在将我的适配器移植到RecyclerView.Adapter

我想实现的是:当用户向下滚动靠近结尾时,我想要开始获取数据,我还想在最后添加ProgressBar视图以让用户知道更多的数据即将到来。

在我的BaseAdapter中实现这一点的方式: getView在接近尾声请求的视图中,我会开始获取更多的数据,调用notifyDataSetChanged(获取ProgressBar视图来显示),然后返回getView所需的视图。

我试过在RecyclerView.Adapter中做的事情我试图做基本相同的事情,这次在onBindViewHolder方法,

但如果我尝试并在此方法内调用notifyItemInserted我收到以下exception:

 IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling 

我试过了:我注意到onLayoutChildrenLayoutManager onBindViewHolder被调用,我试图覆盖它,并调用notifyItemInserted super但我得到了相同的exception

我怎样才能实现我的目标?

Solutions Collecting From Web of "RecyclerView notifyItemInserted IllegalStateException"

  Handler handler = new Handler(); final Runnable r = new Runnable() { public void run() { adapter.notifyDataSetChanged(); } }; handler.post(r); 

我的示例代码,我调用adapter.notifyDataSetChanged(); 从活动

值得注意的是RecyclerView.isComputingLayout()方法中的JavaDoc触发了这个exception:

 /** * Returns whether RecyclerView is currently computing a layout. * <p> * If this method returns true, it means that RecyclerView is in a lockdown state and any * attempt to update adapter contents will result in an exception because adapter contents * cannot be changed while RecyclerView is trying to compute the layout. * <p> * It is very unlikely that your code will be running during this state as it is * called by the framework when a layout traversal happens or RecyclerView starts to scroll * in response to system events (touch, accessibility etc). * <p> * This case may happen if you have some custom logic to change adapter contents in * response to a View callback (eg focus change callback) which might be triggered during a * layout calculation. In these cases, you should just postpone the change using a Handler or a * similar mechanism. * * @return <code>true</code> if RecyclerView is currently computing a layout, <code>false</code> * otherwise */ public boolean isComputingLayout() { return mLayoutOrScrollCounter > 0; } 

突出的词组是:

在这些情况下,您应该使用Handler或类似机制推迟更改。

在我的情况下,我正在修改另一个线程的适配器内容,偶尔会导致冲突。 将更新移动到UI线程上的Handler自然解决了这个问题。

使用Handler程序添加项目和调用notify...()从这个Handler解决了我的问题。

整洁 简单的方法:

  recyclerView.post(new Runnable() { @Override public void run() { adapter.notifyDataSetChanged(); } }); 

说明:您使用您的RecyclerView实例,并在post方法中将一个新的Runnable添加到消息队列中。 runnable将在用户界面线程上运行。 这是Android从后台访问UI线程的限制(例如,在将在后台线程中运行的方法内)。

尝试这个

 if (!recyclerView.isComputingLayout()) { recyclerView.notifyDataSetChanged(); } 

我使用这个:

 Handler handler = new Handler(); private void notifyItemInsertedEx(final int position) { try { notifyItemInserted(position); } catch (Exception ex) { handler.post(new Runnable(){ public void run(){ notifyItemInserted(position); } }); } }