es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Respuesta:

    El mensaje de error indica que notifyDataSetChanged() no puede ser llamado mientras el RecyclerView está realizando un diseño o desplazamiento. Esto se debe a que los datos del adaptador están siendo utilizados actualmente por el RecyclerView y llamar a notifyDataSetChanged() 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 el RecyclerView 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:

    new Handler(Looper.getMainLooper()).post(new Runnable() {
      @Override
      public void run() {
        mAdapter.notifyDataSetChanged();
      }
    });
    

    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 a notifyDataSetChanged() 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:

    updateData();
    // llamar a notifyDataSetChanged() después de que se termine el proceso de diseño actual
    new Handler(Looper.getMainLooper()).post(new Runnable() {
      @Override
      public void run() {
        mAdapter.notifyDataSetChanged();
      }
    });
    

    Esto debería resolver el problema de llamar a notifyDataSetChanged() mientras el RecyclerView está realizando un diseño o desplazamiento.

Comments are closed.