Voici le scénario : L'activité contient un fragment A
qui, à son tour, utilise getChildFragmentManager()
pour ajouter des fragments A1
y A2
dans son onCreate
comme ça :
getChildFragmentManager()
.beginTransaction()
.replace(R.id.fragmentOneHolder, new FragmentA1())
.replace(R.id.fragmentTwoHolder, new FragmentA2())
.commit()
Jusqu'à présent, tout va bien, tout fonctionne comme prévu.
Nous exécutons ensuite la transaction suivante dans l'activité :
getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations(anim1, anim2, anim1, anim2)
.replace(R.id.fragmentHolder, new FragmentB())
.addToBackStack(null)
.commit()
Pendant la transition, le enter
animations pour les fragments B
fonctionne correctement mais les fragments A1 et A2 disparaissent entièrement . Lorsque nous inversons la transaction avec le bouton Back, ils s'initialisent correctement et s'affichent normalement lors de la popEnter
l'animation.
Lors de mes brefs essais, le problème s'est aggravé : si j'ai défini les animations pour les fragments enfants (voir ci-dessous), la fonction exit
l'animation fonctionne par intermittence lorsque nous ajoutons un fragment B
getChildFragmentManager()
.beginTransaction()
.setCustomAnimations(enter, exit)
.replace(R.id.fragmentOneHolder, new FragmentA1())
.replace(R.id.fragmentTwoHolder, new FragmentA2())
.commit()
L'effet que je veux obtenir est simple - je veux que les exit
(ou devrait-on dire popExit
?) animation sur le fragment A
(anim2) à exécuter, animant l'ensemble du conteneur, y compris ses enfants imbriqués.
Y a-t-il un moyen d'y parvenir ?
Editar : Veuillez trouver un cas de test ici
Edit2 : Merci à @StevenByle de m'avoir poussé à continuer d'essayer avec les animations statiques. Apparemment, vous pouvez définir des animations sur une base par opération (et non globale à l'ensemble de la transaction), ce qui signifie que les enfants peuvent avoir une animation statique indéfinie, tandis que leur parent peut avoir une animation différente et le tout peut être validé en une seule transaction. Voir la discussion ci-dessous et le projet de cas de test mis à jour .
0 votes
Qu'est-ce que
R.id.fragmentHolder
par rapport à A, A1, A2, etc ?0 votes
FragmentHolder est un id dans la disposition de l'activité, fragment{One,Two}Holder sont dans la disposition du fragment A. Ces trois éléments sont distincts. Le fragment A a été initialement ajouté dans fragmentHolder (c'est-à-dire que le fragment B remplace le fragment A).
0 votes
J'ai créé un projet type ici : github.com/BurntBrunch/NestedFragmentsAnimationsTest Il y a aussi un apk inclus dans le dépôt. C'est un bug vraiment ennuyeux et je cherche un moyen de le contourner (en supposant que ce n'est pas dans mon code).
0 votes
J'en sais un peu plus sur cette question maintenant. La raison pour laquelle les fragments disparaissent est que les enfants gèrent les événements du cycle de vie avant le parent. En fait, A1 et A2 sont supprimés avant A et comme ils n'ont pas d'animations définies, ils disparaissent brusquement. Une façon d'atténuer quelque peu ce problème est de supprimer explicitement A1 et A2 dans la transaction qui remplace A. De cette façon, ils s'animent lorsqu'ils sortent, mais leur vitesse d'animation est au carré, puisque le conteneur parent s'anime également. Une solution qui ne produise pas cet artefact serait appréciée.
0 votes
Le changement (remplacement du fragment de départ) que vous mentionnez dans la question est le vrai changement que vous voulez faire ou c'est juste un exemple ? Vous allez appeler le
changeFragment
méthode une seule fois ?0 votes
Eh bien, pas nécessairement une seule fois, mais disons que je peux restructurer les choses, de sorte que je ne l'appelle qu'une seule fois. Où cela me mène-t-il ?
0 votes
Pour éviter que le fragment interne ne soit détruit (et animé au fur et à mesure que le parent disparaît), vous pourriez le cacher au lieu d'utiliser un simple
replace
. Donc la transaction dans lechangeFragment
La méthode aura deux opérations, pour cacherFragmentA
et aussiadd
FragmentB
au conteneur. Cela devrait fonctionner à la fois pour les animations de sortie et d'entrée.0 votes
C'est un point valable, mais cela laisse la hiérarchie des vues attachée. Les fragments que j'utilise actuellement sont plutôt lourds et je préfère les créer et les détruire plutôt que de les laisser simplement PARTIR. Merci pour la suggestion, cependant.
0 votes
Que diriez-vous de simuler la présence de fragments imbriqués comme ceci gist.github.com/luksprog/4996190 (gardez à l'esprit que ce que j'ai écrit est très basique) ?
0 votes
@Delyan - avez-vous essayé de définir des animations sur les fragments enfants (avec la même durée que l'animation parent) qui ne s'animent tout simplement pas (translation de 0 à 0). De cette façon, ils se déplaceront simplement avec l'animation de leur parent (tout en s'animant sur place).
0 votes
@Luksprog - c'est follement hacky, j'aime ça ! :) Je vais l'essayer. Je pourrais même essayer d'enregistrer le cache de dessin, au lieu de dessiner la hiérarchie à partir de zéro. StevenByle - Je pensais que FragmentTransactions ne pouvait contenir qu'un seul ensemble d'animations personnalisées (donc l'animation pour retirer les enfants a hérité de l'animation pour retirer le parent, d'où l'augmentation de la vitesse) mais en regardant l'implémentation, il devrait être possible d'avoir différentes animations par opération. Je vais l'essayer et je vous le ferai savoir.
0 votes
@StevenByle - J'ai essayé et ça marche ! Je ne savais pas que l'on pouvait définir des animations par opération dans une transaction, mais c'est le cas et c'est ce qui sauve la journée. N'hésitez pas à l'écrire comme une réponse, afin que je puisse vous donner la prime. Luksprog - Je pense que je vais accepter la réponse de StevenByle car elle est beaucoup plus propre et permet de garder les vues interactives pendant les transitions. Merci beaucoup pour votre temps, cependant ! N'hésitez pas à écrire votre solution comme une réponse pour une référence plus facile.
0 votes
J'ai parlé prématurément. Cette solution fonctionne en avançant (c'est-à-dire en plaçant le fragment avec les enfants sur la pile arrière) mais en retirant la pile arrière de un fragment avec des enfants les fait toujours disparaître.
0 votes
Je suis plus qu'ennuyé mais je vais en fait utiliser la solution de dessin proposée par @Luksprog (avec l'ajout de la vérification du cache de dessin d'abord). Cela ne me demande pas d'ajouter le suivi des fragments enfants et l'interaction avec les fragments reste la même, qu'ils aient des enfants ou non. Je ne suis pas satisfait de cette solution, mais elle fonctionne.