tutorial studio navegar fragments example entre dinamicos diferencia desde activity abrir android android-fragments android-nested-fragment

navegar - fragments dinamicos android studio



Fragmentos dentro de Fragmentos (6)

Me pregunto si esto es realmente un error en la API de Android:

Tengo una configuración como esta:

┌----┬---------┐ | | | | 1 | 2 | | |┌-------┐| | || || | || 3 || └----┴┴-------┴┘

  1. Es un menú que carga el fragmento n. ° 2 (una pantalla de búsqueda) en el panel derecho.
  2. Es una pantalla de búsqueda que contiene el fragmento # 3, que es una lista de resultados.
  3. La lista de resultados se usa en varios lugares (incluso como un fragmento funcional de alto nivel por derecho propio).

Esta funcionalidad funciona perfectamente en un teléfono (donde 1, 2 y 3 son ActivityFragment ).

Sin embargo, cuando usé este código:

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); Fragment frag = new FragmentNumber2(); if(toLoad != null) frag.setArguments(toLoad); transaction.replace(R.id.rightPane, frag); transaction.commit();

Donde R.id.leftPane y R.id.rightPane son <fragment> s en un diseño lineal horizontal.

Tengo entendido que el código anterior elimina el fragmento que es residente y luego lo reemplaza con un nuevo fragmento. Brillante ... Obviamente, eso no es lo que sucede porque cuando este código se ejecuta la segunda vez, obtienes la siguiente excepción:

07-27 15:22:55.940: ERROR/AndroidRuntime(8105): Caused by: java.lang.IllegalArgumentException: Binary XML file line #57: Duplicate id 0x7f080024, tag null, or parent id 0x0 with another fragment for FragmentNumber3

Esto se debe a que el contenedor para FragmentNumber3 se ha duplicado y ya no tiene una ID única. El Fragmento inicial no ha sido destruido (?) Antes de que se agregue el nuevo (en mi opinión eso significa que no ha sido reemplazado ).

¿Puede alguien decirme si esto es posible ( esta respuesta sugiere que no es así) o es un error?


Los fragmentos anidados son compatibles con Android 4.2 y posterior

La Biblioteca de soporte de Android también ahora admite fragmentos anidados , por lo que puede implementar diseños de fragmentos anidados en Android 1.6 y versiones posteriores.

Para anidar un fragmento, simplemente llame a getChildFragmentManager () en el Fragmento en el que desea agregar un fragmento. Esto devuelve un FragmentManager que puede usar como lo hace normalmente desde la actividad de nivel superior para crear transacciones de fragmentos. Por ejemplo, aquí hay un código que agrega un fragmento de una clase Fragment existente:

Fragment videoFragment = new VideoPlayerFragment(); FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); transaction.add(R.id.video_fragment, videoFragment).commit();

Para tener más idea sobre los fragmentos anidados, por favor revisa estos tutoriales
Parte 1
Parte 2
Parte 3

y aquí hay una publicación de SO que discute sobre las mejores prácticas para fragmentos anidados .


.. puedes limpiar tu fragmento anidado en el método destroyview del fragmento padre:

@Override public void onDestroyView() { try{ FragmentTransaction transaction = getSupportFragmentManager() .beginTransaction(); transaction.remove(nestedFragment); transaction.commit(); }catch(Exception e){ } super.onDestroyView(); }


He enfrentado el mismo problema, he luchado un par de días con él y debería decir que la forma más fácil de superar lo encontré con el uso de fragment.hide () / fragment.show () cuando se selecciona / desactiva la pestaña ().

public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) { if (mFragment != null) ft.hide(mFragment); }

Cuando se produce una rotación de pantalla, todos los fragmentos primarios y secundarios se destruyen correctamente.

Este enfoque también tiene una ventaja adicional: usar hide () / show () no hace que las vistas de fragmento pierdan su estado, por lo que no es necesario restaurar la posición de desplazamiento anterior para ScrollViews, por ejemplo.

El problema es que no sé si es correcto no separar los fragmentos cuando no son visibles. Creo que el ejemplo oficial de TabListener está diseñado pensando en que los fragmentos son reutilizables y no deberías contaminar con ellos la memoria, sin embargo, creo que si solo tienes unas pestañas y sabes que los usuarios cambiarán entre ellas frecuentemente, será apropiado para mantenerlos unidos a la actividad actual.

Me gustaría escuchar comentarios de desarrolladores más experimentados.


Los fragmentos anidados no son actualmente compatibles. Intentar colocar un fragmento dentro de la UI de otro fragmento dará como resultado un comportamiento indefinido y posiblemente roto.

Actualización : los fragmentos anidados son compatibles a partir de Android 4.2 (y Android Support Library rev 11): http://developer.android.com/about/versions/android-4.2.html#NestedFragments

NOTA (según http://developer.android.com/about/versions/android-4.2.html#NestedFragments ): " Nota: No se puede inflar un diseño en un fragmento cuando ese diseño incluye un <fragment> . Los fragmentos anidados solo se admiten cuando se agregan a un fragmento de forma dinámica " .


Si encuentra que su fragmento anidado no se elimina o está duplicado (por ejemplo, al reiniciar la actividad, al rotar la pantalla) intente cambiar:

transaction.add(R.id.placeholder, newFragment);

a

transaction.replace(R.id.placeholder, newFragment);

Si lo anterior no ayuda, intente:

Fragment f = getChildFragmentManager().findFragmentById(R.id.placeholder); FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); if (f == null) { Log.d(TAG, "onCreateView: fragment doesn''t exist"); newFragment= new MyFragmentType(); transaction.add(R.id.placeholder, newFragment); } else { Log.d(TAG, "onCreateView: fragment already exists"); transaction.replace(R.id.placeholder, f); } transaction.commit();

Aprendido here


Tengo una aplicación que estoy desarrollando que se presenta de manera similar con las pestañas en la barra de acción que lanza fragmentos, algunos de estos fragmentos tienen múltiples fragmentos incrustados dentro de ellos.

Obtuve el mismo error cuando traté de ejecutar la aplicación. Parece que si crea una instancia de los Fragmentos dentro del diseño xml después de que una pestaña no se haya seleccionado y luego se vuelva a seleccionar, obtendría el error del inflador.

Resolví esto reemplazando todos los fragmentos en xml con Linearlayouts y luego usando una transacción Fragment manager / fragment para instanciar los fragmentos, todo parece funcionar correctamente, al menos en un nivel de prueba en este momento.

Espero que esto te ayude.