RecyclerView notifyItemInserted IllegalStateException



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



 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(); } };; 

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


 /** * 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; } 



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


整洁 简单的方法: 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) { Runnable(){ public void run(){ notifyItemInserted(position); } }); } }