TabLayout roto debido a ViewPager2
Tengo un Tablayout
con 2 pestañas (fragmentos) Home y Contacts, implementados con un ViewPager2
. Los datos en cada fragmento (se solicita una actualización en cada onResume()
de la actividad TabLayout). Como tengo que llamar a adapter.notifyItemChanged(position);
para actualizar los fragmentos, tuve que sobrescribir tanto getItemId
como containsItem
en mi FragmentStateAdapter
, como se explica en la nota azul en esta sección.
El problema es que ahora el TabLayout está roto, si cambio de pestaña, el menú inflado en la pestaña anterior permanece (por ejemplo, el elemento del menú de búsqueda permanece al cambiar de Contactos) y al imprimir algunos registros noté que entra en un bucle. Sin sobrescribir getItemId
y containsItem
, el TabLayout funciona correctamente, pero los datos no se actualizan cuando se actualizan.
Quizás tomar el hash del fragmento no sea una ID única ya que el fragmento se crea usando un objeto (BusinessCard.newInstance(myContact);
) y el segundo uno una lista ContactList.newInstance(listContacts);
.
Cualquier ayuda sería realmente útil ya que estoy completamente perdido.
¡Muchas gracias!
EDITAR:
Si cambio a la pestaña Contactos, comienza a iterar. Registros:
I/TEST: Aquí está 1
I/TEST: Aquí está falso
I/TEST: Aquí está 1
I/TEST: Aquí está falso
I/TEST: ContactList{7e700e} (48ea6f92-44ca-4324-8079-325c865df43e tag=f1) en la posición 1
I/TEST: ContactList{7e700e} (48ea6f92-44ca-4324-8079-325c865df43e tag=f1) en la posición 1
Y en la imagen se puede visualizar el problema. En el fragmento Home, el elemento de búsqueda del menú no debería estar presente. Persiste después de cambiar de Contactos a Home:
davy.ai
Parece que el problema podría estar en la implementación del método
containsItem()
en tuFragmentStateAdapter
. Como sospechaste, usar el hashcode de un fragmento podría no ser un identificador único confiable, especialmente cuando estás recreando el fragmento con diferentes datos.Una mejor manera de implementar
containsItem ()
sería comparar la etiqueta del fragmento con elitemId
pasado (que estableces en la etiqueta del fragmento en el métodogetItemId ()
). Aquí hay una implementación modificada decontainsItem ()
que debería funcionar:Este método primero encuentra el fragmento con la etiqueta que coincide con el
itemId
pasado y luego compara elitemId
con elgetItemId()
del fragmento en la posición encontrada. Si lositemId
s coinciden, devuelvetrue
, lo que indica que el adaptador contiene el elemento.Con esta modificación, deberías poder usar los métodos
getItemId()
ycontainsItem()
para actualizar tus fragmentos sin romper la funcionalidad del TabLayout.