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.
- RecyclerView: cómo borrar las vistas en caché / reciclado?
- RecyclerView imágenes desaparecidas
- Uso de JsonArray vs ArrayList como conjunto de datos para RecyclerView Adapter
- No se puede llamar al método notifyItemInserted en una devolución de llamada de desplazamiento recyclerview-v7: 24.2.0
- RecyclerView obtiene aplastado cuando se utiliza notifyItemChanged de Handler utilizando Runnable
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.
- El mejor lugar para llamar a RecyclerView.Adapter.notifyItem *?
- NotifyItemChanged (int position) actualiza varios elementos en RecyclerView
- Actualizaciones de datos de RecyclerView y Adaptador
- RecyclerView actualiza sólo en desplazamiento
- Cómo pasar valores de RecycleAdapter a MainActivity u Otras actividades
- RecyclerView StaggeredGridLayoutManager problema de reordenación
- Android animando recyclerview
- ¿Cómo guardar el estado del elemento de la fila RecyclerView?
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.
- Actualizar base de datos sqlite cuando se actualiza la base de datos del servidor
- RippleDrawable máscara de color, ¿para qué sirve?