Au moment de l'exécution, un objet FragmentManager
peut ajouter, supprimer, remplacer et effectuer d'autres actions avec des fragments en réponse à une interaction avec l'utilisateur. Chaque ensemble de modifications de fragment que vous validez est appelé transaction. Vous pouvez spécifier ce qu'il faut faire à l'intérieur de la transaction à l'aide des API fournies par la classe FragmentTransaction
. Vous pouvez regrouper plusieurs actions dans une seule transaction. Par exemple, une transaction peut ajouter ou remplacer plusieurs fragments. Ce regroupement peut être utile lorsque plusieurs fragments frères sont affichés sur le même écran, par exemple avec des affichages fractionnés.
Vous pouvez enregistrer chaque transaction dans une pile "Retour" gérée par FragmentManager
, ce qui permet à l'utilisateur de faire défiler les modifications de fragment en arrière, comme il est possible de le faire pour les activités.
Vous pouvez obtenir une instance de FragmentTransaction
à partir de FragmentManager
en appelant beginTransaction()
, comme illustré dans l'exemple suivant :
Kotlin
val fragmentManager = ... val fragmentTransaction = fragmentManager.beginTransaction()
Java
FragmentManager fragmentManager = ... FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Le dernier appel sur chaque FragmentTransaction
doit valider la transaction.
L'appel commit()
indique à FragmentManager
que toutes les opérations ont été ajoutées à la transaction.
Kotlin
val fragmentManager = ... // The fragment-ktx module provides a commit block that automatically // calls beginTransaction and commit for you. fragmentManager.commit { // Add operations here }
Java
FragmentManager fragmentManager = ... FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); // Add operations here fragmentTransaction.commit();
Autoriser la réorganisation des modifications d'état de fragment
Chaque FragmentTransaction
doit utiliser setReorderingAllowed(true)
:
Kotlin
supportFragmentManager.commit { ... setReorderingAllowed(true) }
Java
FragmentManager fragmentManager = ... fragmentManager.beginTransaction() ... .setReorderingAllowed(true) .commit();
Pour des raisons de compatibilité de comportements, l'indicateur de réorganisation n'est pas activé par défaut.
Il est toutefois nécessaire d'autoriser FragmentManager
à exécuter correctement FragmentTransaction
, en particulier lorsqu'il fonctionne sur la pile "Retour" et qu'il exécute des animations et des transitions. L'activation de cet indicateur garantit que si plusieurs transactions sont exécutées ensemble, les fragments intermédiaires (c'est-à-dire ceux qui sont ajoutés puis remplacés immédiatement) ne subissent pas de modifications du cycle de vie, et leurs animations ou transitions ne sont pas exécutées. Notez que cet indicateur affecte à la fois l'exécution initiale de la transaction et l'annulation de la transaction avec popBackStack()
.
Ajouter et supprimer des fragments
Pour ajouter un fragment à un FragmentManager
, appelez add()
sur la transaction. Cette méthode reçoit l'identifiant du conteneur pour le fragment, ainsi que le nom de classe du fragment que vous souhaitez ajouter. Le fragment ajouté passe à l'état RESUMED
. Il est vivement recommandé que le conteneur soit un FragmentContainerView
faisant partie de la hiérarchie des affichages.
Pour supprimer un fragment de l'hôte, appelez remove()
en transmettant une instance de fragment récupérée du gestionnaire de fragments via findFragmentById()
ou findFragmentByTag()
.
Si l'affichage du fragment a déjà été ajouté à un conteneur, l'affichage est alors supprimé du conteneur à ce stade. Le fragment supprimé passe à l'état DESTROYED
.
Utilisez replace()
pour remplacer un fragment existant dans un conteneur par une instance de la nouvelle classe de fragment que vous fournissez. L'appel de replace()
équivaut à appeler remove()
avec un fragment dans un conteneur et à ajouter un fragment à ce même conteneur.
L'extrait de code suivant montre comment remplacer un fragment par un autre :
Kotlin
// Create new fragment val fragmentManager = // ... // Create and commit a new transaction fragmentManager.commit { setReorderingAllowed(true) // Replace whatever is in the fragment_container view with this fragment replace<ExampleFragment>(R.id.fragment_container) }
Java
// Create new fragment and transaction FragmentManager fragmentManager = ... FragmentTransaction transaction = fragmentManager.beginTransaction(); transaction.setReorderingAllowed(true); // Replace whatever is in the fragment_container view with this fragment transaction.replace(R.id.fragment_container, ExampleFragment.class, null); // Commit the transaction transaction.commit();
Dans cet exemple, une nouvelle instance de ExampleFragment
remplace, le cas échéant, le fragment qui se trouve actuellement dans le conteneur de mise en page identifié par R.id.fragment_container
.
Par défaut, les modifications apportées à une FragmentTransaction
ne sont pas ajoutées à la pile "Retour". Pour enregistrer ces modifications, vous pouvez appeler addToBackStack()
sur la FragmentTransaction
. Pour en savoir plus, consultez la page Gestionnaire de fragments.
Le commit est asynchrone
L'appel de commit()
ne permet pas d'effectuer la transaction immédiatement. La transaction est programmée pour s'exécuter sur le thread UI principal dès qu'elle le peut. Toutefois, si nécessaire, vous pouvez appeler commitNow()
pour exécuter immédiatement la transaction de fragment sur votre thread UI.
Notez que commitNow
n'est pas compatible avec addToBackStack
. Sinon, vous pouvez exécuter toutes les FragmentTransactions
en attente envoyées par des appels commit()
qui ne sont pas encore exécutées en appelant executePendingTransactions()
. Cette approche est compatible avec addToBackStack
.
Pour la grande majorité des cas d'utilisation, commit()
suffit.
L'ordre des opérations est important
L'ordre dans lequel vous effectuez les opérations dans un FragmentTransaction
est important, en particulier lorsque vous utilisez setCustomAnimations()
. Cette méthode applique les animations données à toutes les opérations de fragment qui le suivent.
Kotlin
supportFragmentManager.commit { setCustomAnimations(enter1, exit1, popEnter1, popExit1) add<ExampleFragment>(R.id.container) // gets the first animations setCustomAnimations(enter2, exit2, popEnter2, popExit2) add<ExampleFragment>(R.id.container) // gets the second animations }
Java
getSupportFragmentManager().beginTransaction() .setCustomAnimations(enter1, exit1, popEnter1, popExit1) .add(R.id.container, ExampleFragment.class, null) // gets the first animations .setCustomAnimations(enter2, exit2, popEnter2, popExit2) .add(R.id.container, ExampleFragment.class, null) // gets the second animations .commit()
Limiter le cycle de vie du fragment
FragmentTransactions
peut affecter l'état du cycle de vie des fragments individuels ajoutés dans le champ d'application de la transaction. Lors de la création d'une FragmentTransaction
, setMaxLifecycle()
définit un état maximal pour le fragment donné. Par exemple, ViewPager2
utilise setMaxLifecycle()
pour limiter les fragments hors écran à l'état STARTED
.
Afficher et masquer les affichages de fragment
Utilisez les méthodes show()
et hide()
de FragmentTransaction
pour afficher et masquer l'affichage des fragments qui ont été ajoutés à un conteneur.
Ces méthodes définissent la visibilité des affichages du fragment sans affecter le cycle de vie du fragment.
Bien qu'il ne soit pas nécessaire d'utiliser une transaction de fragment pour activer ou désactiver la visibilité des affichages dans un fragment, ces méthodes sont utiles dans les cas où vous souhaitez associer les modifications de l'état de visibilité aux transactions dans la pile "Retour".
Associer et dissocier des fragments
La méthode detach()
de FragmentTransaction
dissocie le fragment de l'interface utilisateur, et détruit ainsi la hiérarchie des affichages. Le fragment reste dans le même état (STOPPED
) que lorsqu'il est placé sur la pile "Retour".
Cela signifie que le fragment a été supprimé de l'interface utilisateur, mais qu'il est toujours géré par le gestionnaire de fragments.
La méthode attach()
associe à nouveau un fragment dont il a été précédemment dissocié.
Ainsi, la hiérarchie des affichages est recréée, associée à l'interface utilisateur et affichée.
Étant donné qu'une FragmentTransaction
est traitée comme un ensemble atomique unique d'opérations, les appels detach
et attach
sur la même instance de fragment dans la même transaction s'annulent mutuellement, et permet ainsi d'éviter la destruction et la recréation immédiate de l'interface utilisateur du fragment. Si vous souhaitez dissocier puis réassocier immédiatement un fragment, utilisez des transactions distinctes séparées par executePendingOperations()
si vous utilisez commit()
.