RecyclerView findViewHolder null para elementos fuera de pantalla

[Primera vez asker y codificador androide de primera vez así que pido disculpas si hago algo mal]

Estoy intentando cambiar el valor dentro de un itemview en mi reciclador. Sin embargo, si esa visualización de elementos aparece fuera de pantalla, findViewBy [layout, adapter o id] aparece null.

public void setUserActive(UserListAdapter adapter, RecyclerView recyclerView, int position, View v) {recyclerView.findViewHolderForItemId(adapter.getItemId(position)); TextView txtActive = (TextView) vh.itemView.findViewById(R.id.user_isActive); txtActive.setText("Active"); UserListAdapter.ViewHolder inactivevh = (UserListAdapter.ViewHolder) recyclerView.findViewHolderForItemId(adapter.getItemId(adapter.getActiveUserPosition())); TextView txtInActive = (TextView) inactivevh.itemView.findViewById(R.id.user_isActive); txtInActive.setText(""); adapter.setActiveUserPosition(position); } 

He intentado algunas maneras diferentes de usar

  UserListAdapter.ViewHolder vh = (UserListAdapter.ViewHolder) recyclerView.findViewHolderForLayoutPosition(position); 

o

 UserListAdapter.ViewHolder inactivevh = (UserListAdapter.ViewHolder) recyclerView.findViewHolderForAdapterPosition(position) 

Y todos fallan cuando la vista que debe estar inactiva vh está fuera de pantalla.

He fijado el adaptador a hasStableIDs = true notifydatasetchanged no parece ayudar tampoco.

Si un elemento está en la pantalla (presentado) puede obtener su soporte de vista convenientemente utilizando los métodos que ha descrito. Si un elemento no está en la pantalla, se actualizará tan pronto como se onBindViewHolder través de onBindViewHolder . Si no se desplaza, no se presenta al usuario. Ergo cualquier intento de actualizar es un desperdicio de poder de procesamiento (aparte de ser imposible porque el elemento no tiene un titular de vista asignado).

Significado: Implemente su adaptador de tal manera que onBindViewHolder es capaz de extraer datos actualizados. Parece que estás preparado y puedes usar esto:

 public void setUserActive(UserListAdapter adapter, RecyclerView recyclerView, int position) { // Retrieve the old active user ID so we can mark him deactivated. final int oldUserActivePosition = adapter.getActiveUserPosition(); // Setup the adapter with current data. adapter.setActiveUserPosition(position); // Do NOT use stable IDs and this method. It just doesn't work as expected. // recyclerView.findViewHolderForItemId(adapter.getItemId(position)); // Activate new user. UserListAdapter.ViewHolder holder = (UserListAdapter.ViewHolder) recyclerView.findViewHolderForAdapterPosition(position); if (holder == null) { // The item is off screen, no need to update it yet. } else { // Update the on screen item. The logic is already implemented in the adapter. adapter.onBindViewHolder(holder, position); } // Deactivate previous user. holder = (UserListAdapter.ViewHolder) recyclerView.findViewHolderForAdapterPosition(oldUserActivePosition); if (holder != null) { adapter.onBindViewHolder(holder, oldUserActivePosition); } } 

Simplifique el bloque if-else en su código por supuesto.

EDITAR:

Me di cuenta de lo innecesariamente complicado que es la solución original. Siempre y cuando el adaptador puede reaccionar a todos los eventos que necesita en onBindViewHolder y el enlace es realmente fácil esto será suficiente:

 public void setActiveUserPosition(int position) { if (mActiveUserPosition != position) { int oldPosition = mActiveUserPosition; mActiveUserPosition = position; notifyItemChanged(oldPosition); notifyItemChanged(position); } } 

Todo lo que necesita para llamar ahora es adapter.setActiveUserPosition(position); Que hace que el método setUserActive sea ​​obsoleto.

  • Equivalente de ListView.setEmptyView en RecyclerView
  • Color de fondo o imágenes barajando en desplazamiento en recyclerview?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.