RecyclerView notifyItemInserted IllegalStateException

Estoy portando mi adaptador en RecyclerView.Adapter

Lo que quiero lograr: cuando el usuario se desplaza hacia abajo cerca del final quiero empezar a buscar los datos, también quiero añadir i ProgressBar ver al final para que el usuario sepa más datos está llegando.

La forma en que implementé esto en mi BaseAdapter: en getView en la vista solicitada en cerca del final, empezaría a buscar más datos, llamar a notifyDataSetChanged (para obtener la vista ProgressBar para mostrar) y sólo entonces devolver la vista necesaria para getView .

Lo que intenté hacer en RecyclerView.Adapter: traté de hacer lo mismo básicamente, esta vez en el método onBindViewHolder ,

Pero si trato de llamar a notifyItemInserted dentro de este método obtengo la siguiente excepción:

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

Lo que onBindViewHolder intentado: me di cuenta de que onBindViewHolder se llama desde onLayoutChildren de LayoutManager , traté de reemplazarlo y llamar a notifyItemInserted después de su super pero tengo la misma excepción

¿Cómo puedo lograr mi meta?

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

Mi código de ejemplo donde llamo adapter.notifyDataSetChanged (); De la actividad

También vale la pena destacar el JavaDoc en el método RecyclerView.isComputingLayout() que activa esta excepción:

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

La frase más destacada es:

En estos casos, sólo debe posponer el cambio utilizando un controlador o un mecanismo similar.

En mi caso, estaba modificando el contenido del adaptador de otro hilo, que estaba (ocasionalmente) causando una colisión. Cambiar la actualización a un controlador en el subproceso de interfaz de usuario resuelve esto naturalmente.

El uso de un Handler para agregar elementos y llamar a notify...() de este Handler arregló el problema para mí.

Forma limpia y sencilla :

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

Explicación: Utiliza la instancia de RecyclerView y dentro del método de Runnable agrega un nuevo Runnable a la cola de mensajes. El runnable se ejecutará en el hilo de la interfaz de usuario. Este es un límite para Android para acceder al subproceso de interfaz de usuario desde el fondo (por ejemplo, dentro de un método que se ejecutará en un subproceso de fondo).

Prueba esto

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

Yo uso esto:

 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); } }); } } 
  • RecyclerView.Adapter.notifyItemMoved (0,1) desplaza la pantalla
  • Cómo obtener la posición en onCreateViewHolder
  • El mejor lugar para adjuntar onClickListener en recyclerview
  • Lista 2D con RecyclerView en HorizontalScrollView
  • Android: ¿Cómo obtener el actual desplazamiento X de RecyclerView?
  • RecyclerView onItemClick Listener
  • Datos de SQLite a un RecyclerView
  • ¿Debo cambiar el Listview existente en mi aplicación a RecyclerView?
  • Android: Actualización de recyclerview con nuevos datos
  • Prueba recyclerView con Espresso, cómo realizar clics o hacer afirmaciones
  • Uso de CardView y RecyclerView en mis archivos de diseño genera una excepción
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.