Je me demande s'il s'agit en fait d'un bogue dans l'API Android:
J'ai une configuration comme celle-ci:
┌----┬---------┐
| | |
| 1 | 2 |
| |┌-------┐|
| || ||
| || 3 ||
└----┴┴-------┴┘
- Est un menu qui charge le fragment # 2 (Un écran de recherche) dans le volet de droite.
- Est un écran de recherche qui contient le fragment # 3, qui est une liste de résultats.
- La liste de résultats est utilisée à plusieurs endroits (y compris en tant que fragment de haut niveau fonctionnel à part entière).
Cette fonctionnalité fonctionne parfaitement bien sur un téléphone (où 1 & 2 et 3 sont ActivityFragment
s).
Cependant, lorsque j'ai utilisé ce code:
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
Fragment frag = new FragmentNumber2();
if(toLoad != null) frag.setArguments(toLoad);
transaction.replace(R.id.rightPane, frag);
transaction.commit();
Où R.id.leftPane
et R.id.rightPane
sont <fragment>
dans une disposition linéaire horizontale.
Je crois comprendre que le code ci-dessus supprime le fragment qui est résident, puis le remplace par un nouveau fragment. Brillant ... Évidemment, ce n'est pas ce qui se passe car lorsque ce code s'exécute la deuxième fois, vous obtenez l'exception suivante:
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
Cela est dû au fait que le conteneur de FragmentNumber3 a été dupliqué et qu'il n'a plus d'ID unique. Le fragment initial n'a pas été détruit (?) Avant l'ajout du nouveau (dans mon esprit, cela signifie qu'il n'a pas été remplacé ).
Quelqu'un peut-il me dire si c'est possible ( cette réponse suggère que ce n'est pas le cas) ou est-ce un bug?
Réponses:
Les fragments imbriqués ne sont actuellement pas pris en charge. Essayer de mettre un fragment dans l'interface utilisateur d'un autre fragment entraînera un comportement non défini et probablement rompu.
REMARQUE (selon ce document ): " Remarque: vous ne pouvez pas gonfler une mise en page en un fragment lorsque cette mise en page comprend un
<fragment>
. Les fragments imbriqués ne sont pris en charge que lorsqu'ils sont ajoutés dynamiquement à un fragment. "la source
Fragment
font désormais partie de l'API Android, oui! developer.android.com/about/versions/… .La bibliothèque de support Android prend désormais également en charge les fragments imbriqués , vous pouvez donc implémenter des conceptions de fragments imbriqués sur Android 1.6 et versions ultérieures.
Pour imbriquer un fragment, appelez simplement getChildFragmentManager () sur le fragment dans lequel vous souhaitez ajouter un fragment. Cela renvoie un FragmentManager que vous pouvez utiliser comme vous le faites normalement à partir de l'activité de niveau supérieur pour créer des transactions de fragment. Par exemple, voici du code qui ajoute un fragment à partir d'une classe Fragment existante:
Pour avoir plus d'idées sur les fragments imbriqués, veuillez parcourir ces tutoriels
Partie 1
Partie 2
Partie 3
et voici un article SO qui traite des meilleures pratiques pour les fragments imbriqués .
la source
.. vous pouvez nettoyer votre fragment imbriqué dans la
destroyview
méthode du fragment parent :la source
J'ai une application que je développe qui est présentée de manière similaire avec des onglets dans la barre d'action qui lance des fragments, certains de ces fragments ont plusieurs fragments incorporés en eux.
J'obtenais la même erreur lorsque j'ai essayé d'exécuter l'application. Il semble que si vous instanciez les fragments dans la mise en page XML après qu'un onglet ait été désélectionné puis resélectionné, j'obtiendrais l'erreur inflator.
J'ai résolu ce problème en remplaçant tous les fragments en xml par des Linearlayouts, puis en utilisant un gestionnaire de fragments / une transaction de fragment pour instancier les fragments, tout semble fonctionner correctement au moins au niveau du test pour le moment.
J'espère que cela vous aidera.
la source
J'ai été confronté au même problème, j'ai eu du mal quelques jours avec cela et je dois dire que le moyen le plus simple de le surmonter est d'utiliser fragment.hide () / fragment.show () lorsque l'onglet est sélectionné / désélectionné ().
Lorsque la rotation de l'écran se produit, tous les fragments parents et enfants sont correctement détruits.
Cette approche présente également un avantage supplémentaire: l'utilisation de hide () / show () ne fait pas perdre aux vues fragmentées leur état, il n'est donc pas nécessaire de restaurer la position de défilement précédente pour ScrollViews par exemple.
Le problème est que je ne sais pas s'il est correct de ne pas détacher les fragments lorsqu'ils ne sont pas visibles. Je pense que l'exemple officiel de TabListener est conçu en pensant que les fragments sont réutilisables et que vous ne devriez pas polluer avec eux la mémoire, cependant, je pense que si vous n'avez que quelques onglets et que vous savez que les utilisateurs basculeront fréquemment entre eux, il sera approprié pour les garder attachés à l'activité en cours.
J'aimerais entendre les commentaires de développeurs plus expérimentés.
la source
Si vous constatez que votre fragment imbriqué n'est pas supprimé ou dupliqué (par exemple, lors du redémarrage de l'activité, lors de la rotation de l'écran), essayez de changer:
à
Si ci-dessus ne vous aide pas, essayez:
Appris ici
la source