Reading time: 3 minutes
Sometimes when using a RecyclerView in Android, we may encounter the problem of it not “clearing the buffer” of content from the corresponding Row for an item in a list. In other words, an item in the list retains the same properties as the item below or the previous item.
To describe it, let me show you a video of the problem.
This video shows the following:
- We create a 4-player game in Infection: Card Game. The game is displayed correctly, showing 4 players.
- Then we create a private game for 2 players, and the game is also displayed correctly in the list.
- But finally, we create a game for 3 players, and the game is displayed as 2 players.
The result is that the last list created for game number 435 should be displayed with space for 3 players, not 2.
Now let’s analyze the code where everything seems to be correct.
@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); } ... }
In the code, I indicate that if the game is for 3 players, hide the name (TextView) and image (ImageView) for player 4, and if the game is for 2 players, do the same for player 3.
Apparently, the code is correct. But the RecyclerView has a bug that, when a game is for 2 players and the next one is for 3, it keeps the TextView and ImageView for player 3 and 4 hidden.
This also happens with the background of the Rows of the RecyclerView (if they have a background color, you can see that it duplicates and behaves strangely).
To solve this problem, we need to set the default value of the list items we want to change, in this case, the RecyclerView and TextView. We do the following:
We set the default value as View.VISIBLE for all the elements.
@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); } ... }
By adding the initial lines, we set the default value for the image and name of the players. This way, the RecyclerView is “cleared,” and the elements are displayed correctly.