Me pregunto si esto es realmente un error en la API de Android:
Tengo una configuración así:
┌----┬---------┐
| | |
| 1 | 2 |
| |┌-------┐|
| || ||
| || 3 ||
└----┴┴-------┴┘
- Es un menú que carga el fragmento n. ° 2 (Una pantalla de búsqueda) en el panel derecho.
- Es una pantalla de búsqueda que contiene el fragmento n. ° 3, que es una lista de resultados.
- 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 y 2 y 3 son ActivityFragment
s).
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
están <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 ).
¿Alguien puede decirme si esto es posible ( esta respuesta sugiere que no lo es) o es un error?
Respuestas:
Los fragmentos anidados no son compatibles actualmente. Intentar colocar un fragmento dentro de la interfaz de usuario de otro fragmento dará como resultado un comportamiento indefinido y probablemente roto.
NOTA (según esta documentación ): " Nota: No puede inflar un diseño en un fragmento cuando ese diseño incluye un
<fragment>
. Los fragmentos anidados solo son compatibles cuando se agregan dinámicamente a un fragmento " .fuente
Fragment
ahora son parte de la API de Android, ¡sí! developer.android.com/about/versions/… .La Biblioteca de soporte de Android ahora también admite fragmentos anidados , por lo que puede implementar diseños de fragmentos anidados en Android 1.6 y superior.
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 fragmentarias. Por ejemplo, aquí hay un código que agrega un fragmento dentro de una clase Fragment existente:
Para tener más idea sobre los fragmentos anidados, consulte estos tutoriales
Parte 1
Parte 2
Parte 3
y aquí hay una publicación SO que discute sobre las mejores prácticas para fragmentos anidados .
fuente
.. puede limpiar su fragmento anidado en el
destroyview
método del fragmento principal :fuente
Tengo una aplicación que estoy desarrollando que se presenta de forma similar a las pestañas en la barra de acción que lanza fragmentos, algunos de estos fragmentos tienen múltiples fragmentos incrustados dentro de ellos.
Recibía el mismo error cuando intenté 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 un administrador de fragmentos / transacción de fragmentos para instanciar los fragmentos, todo parece funcionar correctamente al menos en un nivel de prueba en este momento.
Espero que esto te ayude.
fuente
Me he enfrentado con 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 que encontré esto es usar fragment.hide () / fragment.show () cuando la pestaña está seleccionada / no seleccionada ()
Cuando se produce la rotación de la pantalla, todos los fragmentos primarios y secundarios se destruyen correctamente.
Este enfoque también tiene una ventaja adicional: el uso de hide () / show () no hace que las vistas de fragmentos 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 fragmentos cuando no son visibles. Creo que el ejemplo oficial de TabListener está diseñado pensando que los fragmentos son reutilizables y que no debes contaminarlos con la memoria, sin embargo, creo que si solo tienes unas pocas pestañas y sabes que los usuarios cambiarán entre ellas con frecuencia. será apropiado mantenerlos unidos a la actividad actual.
Me gustaría escuchar comentarios de desarrolladores más experimentados.
fuente
Si encuentra que su fragmento anidado no se elimina o duplica (por ejemplo, en el reinicio de la actividad, en la rotación de la pantalla) intente cambiar:
a
Si lo anterior no ayuda, intente:
Aprendí aquí
fuente