es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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:
Breken TabLayout

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Parece que el problema podría estar en la implementación del método containsItem() en tu FragmentStateAdapter. 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 el itemId pasado (que estableces en la etiqueta del fragmento en el método getItemId ()). Aquí hay una implementación modificada de containsItem () que debería funcionar:

    @Override
    public boolean containsItem(long itemId) {
        String tag = "f" + getItemPosition(itemId);
        Fragment fragment = fragmentManager.findFragmentByTag(tag);
        return fragment != null && itemId == getItemId(getItemPosition(fragment));
    }
    

    Este método primero encuentra el fragmento con la etiqueta que coincide con el itemId pasado y luego compara el itemId con el getItemId() del fragmento en la posición encontrada. Si los itemIds coinciden, devuelve true, lo que indica que el adaptador contiene el elemento.

    Con esta modificación, deberías poder usar los métodos getItemId() y containsItem() para actualizar tus fragmentos sin romper la funcionalidad del TabLayout.

Comments are closed.