Solucionar problema de refresco en RecyclerViews

Tiempo de lectura: 3 minutos

A veces cuándo utilizamos un RecyclerView en Android, podemos encontrarnos con el problema de que no «limpia bien el buffer» de contenido del Row correspondiente a un elemento de una lista. En otras palabras, que un elemento de la lista, conserva las mismas propiedades que el elemento que tiene abajo o elemento anterior.

Para describirlo, os muestro un vídeo sobre el problema.

En este vídeo se muestra lo siguiente:

  1. Creamos una partida de 4 jugadores en Infection: Juego de cartas. La partida se visualiza correctamente mostrando 4 jugadores.
  2. Luego creamos una partida privada de 2 jugadores, la partida también se visualiza correctamente en la lista.
  3. Pero finalmente se crea una partida de 3 jugadores y la partida se visualiza cómo 2 jugadores.

El resultado es qué la última lista creada para la partida número 435 debería mostrarse con hueco de 3 jugadores y no de 2.

Cómo veis en la imagen, la partida 435 aparece cómo partida de 2 jugadores y realmente hemos creado una de 3 jugadores.

Ahora pasamos a analizar el código dónde aparentemente está todo correcto.

    @Override
    public void onBindViewHolder(@NonNull ListaPartidasViewHolder holder, final int position) {

     ...
           if (partidaActual.getNum_jugadores() == 3) {
                holder.nombre_j4.setVisibility(View.GONE);
                holder.imagen_j4.setVisibility(View.GONE);
            }

            if (partidaActual.getNum_jugadores() == 2) {
                holder.imagen_j3.setVisibility(View.GONE);
                holder.imagen_j4.setVisibility(View.GONE);
                holder.nombre_j3.setVisibility(View.GONE);
                holder.nombre_j4.setVisibility(View.GONE);
            }
     ...

}

En el código indico que si la partida es de 3 jugadores, oculte el nombre (TextView) y la Imagen (ImageView) y si la partida es de 2 jugadores, hacemos lo mismo para el jugador 3.

Aparentemente, el código está bien. Pero el RecyclerView tiene un bug, qué cuándo una partida es de 2 jugadores y la siguiente es de 3, mantiene ocultos el TextView e ImageView del jugador 3 y 4.

Esto ocurre también con el fondo de las Rows del RecyclerView (si tienen color de fondo, te das cuenta de que se duplica y se comporta de forma extraña).

Para solucionar este problema, hay que indicar por defecto el valor de los elementos de la lista que queremos cambiar, en este caso el RecyclerView y TextView. Para ello hacemos lo siguiente:

Indicamos el valor por defecto como View.VISIBLE para todos los elementos.

    @Override
    public void onBindViewHolder(@NonNull ListaPartidasViewHolder holder, final int position) {

     ...
            holder.imagen_j3.setVisibility(View.VISIBLE);
            holder.imagen_j4.setVisibility(View.VISIBLE);
            holder.nombre_j3.setVisibility(View.VISIBLE);
            holder.nombre_j4.setVisibility(View.VISIBLE);

           if (partidaActual.getNum_jugadores() == 3) {
                holder.nombre_j4.setVisibility(View.GONE);
                holder.imagen_j4.setVisibility(View.GONE);
            }

            if (partidaActual.getNum_jugadores() == 2) {
                holder.imagen_j3.setVisibility(View.GONE);
                holder.imagen_j4.setVisibility(View.GONE);
                holder.nombre_j3.setVisibility(View.GONE);
                holder.nombre_j4.setVisibility(View.GONE);
            }
     ...

}

Añadiendo las primeras líneas, indicamos el valor por defecto para la imagen y nombre de los jugadores. De esta forma se «limpia» el RecyclerView y ya se muestran los elementos correctamente.

Entonces la partida 435 ya muestra bien el número de jugadores, ya que «limpia el buffer»

Es un caso especial dentro de los RecyclerView, cuya solución es sencilla: Poner primero el valor por defecto del elemento que se quiere modificar y luego cambiarlo según el caso. De esta forma el bug del RecyclerView desaparece y ya muestra las celdas bien.

Deja un comentario