Secciones de Recyclerview: IllegalStateException al llamar a notifyDataSetChanged()
Al utilizar este adaptador de sección simple en mi aplicación para crear dos secciones en RecyclerView, todo funciona bien, pero el problema está en la clase SimpleSectionedRecyclerViewAdapter.java cuando se llama a notifyDataSetChanged();.
El código de error es el siguiente:
mBaseAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
public void onChanged() {
mValid = mBaseAdapter.getItemCount()>0;
notifyDataSetChanged(); // <------------------------el error está aquí
}
@Override
.
.
.
});
En mi fragmento, agregué dos tipos de datos “tareas sin terminar” y “tareas terminadas” a RecyclerView y cada sección tiene el tamaño de sus elementos, la posición de inicio de la segunda sección cambiará según el tamaño de “tareas sin terminar”.
Por ejemplo, tengo “5 tareas” y todas están en la sección “tareas sin terminar”, así que al hacer clic en un elemento en RecyclerView, la tarea se terminará y ahora necesito llamar a notifyDataSetChanged(); para que el resultado sea “4 elementos en la sección de tareas sin terminar” y “se añadirá 1 elemento a la sección de tareas terminadas”.
Todo funciona bien, pero los datos en RecyclerView no cambian y cuando llamo a notifyDataSetChanged();, la aplicación se bloquea y muestra el siguiente error:
java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling androidx.recyclerview.widget.RecyclerView
Entonces, comenté notifyDataSetChanged(); y los datos en RecyclerView no cambian, excepto cuando vuelvo a abrir el fragmento.
¿Alguna ayuda sobre cómo puedo resolver esto?
davy.ai
Respuesta:
El mensaje de error indica que
notifyDataSetChanged()
no puede ser llamado mientras elRecyclerView
está realizando un diseño o desplazamiento. Esto se debe a que los datos del adaptador están siendo utilizados actualmente por elRecyclerView
y llamar anotifyDataSetChanged()
interrumpiría este proceso, lo que conduciría a un comportamiento impredecible.Una posible solución es mover la llamada a
notifyDataSetChanged()
a un momento posterior en el que elRecyclerView
no esté realizando un diseño o desplazamiento. Una forma de lograr esto es enviando un objeto Runnable a la cola de mensajes del hilo principal, que se ejecutará después de que se termine el proceso de diseño actual.Aquí tienes un ejemplo:
Este código crea un nuevo objeto Handler que está asociado a la cola de mensajes del hilo principal. El método
post()
recibe un objeto Runnable que se ejecutará en la cola de mensajes del hilo principal en algún momento en el futuro. En este caso, estamos enviando un mensaje al hilo principal para llamar anotifyDataSetChanged()
después de que se termine el proceso actual de diseño.Puedes usar este código después de haber actualizado los datos en el adaptador, de esta manera:
Esto debería resolver el problema de llamar a
notifyDataSetChanged()
mientras elRecyclerView
está realizando un diseño o desplazamiento.