Während der Laufzeit kann ein FragmentManager
Fragmente als Reaktion auf Nutzerinteraktionen hinzufügen, entfernen, ersetzen und andere Aktionen ausführen. Jede Reihe von Fragmentänderungen, die Sie bestätigen, wird als Transaktion bezeichnet. Mithilfe der APIs der Klasse FragmentTransaction
können Sie angeben, was in der Transaktion geschehen soll. Sie können mehrere Aktionen in einer einzigen Transaktion gruppieren. So können Sie beispielsweise mit einer Transaktion mehrere Fragmente hinzufügen oder ersetzen. Diese Gruppierung kann nützlich sein, wenn mehrere gleichgeordnete Fragmente auf demselben Bildschirm angezeigt werden, z. B. in geteilten Ansichten.
Sie können jede Transaktion in einem Backstack speichern, der von der FragmentManager
verwaltet wird. So kann der Nutzer die Fragmentänderungen rückwärts durchgehen, ähnlich wie bei Aktivitäten.
Sie können eine Instanz von FragmentTransaction
aus der FragmentManager
abrufen, indem Sie beginTransaction()
aufrufen, wie im folgenden Beispiel gezeigt:
Kotlin
val fragmentManager = ... val fragmentTransaction = fragmentManager.beginTransaction()
Java
FragmentManager fragmentManager = ... FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Der letzte Aufruf für jede FragmentTransaction
muss die Transaktion bestätigen.
Der commit()
-Aufruf signalisiert der FragmentManager
, dass alle Vorgänge der Transaktion hinzugefügt wurden.
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();
Neuanordnung von Fragmentstatusänderungen zulassen
Für jeden FragmentTransaction
sollte setReorderingAllowed(true)
verwendet werden:
Kotlin
supportFragmentManager.commit { ... setReorderingAllowed(true) }
Java
FragmentManager fragmentManager = ... fragmentManager.beginTransaction() ... .setReorderingAllowed(true) .commit();
Aus Gründen der Verhaltenskompatibilität ist das Flag für die Neuanordnung standardmäßig deaktiviert.
Sie müssen jedoch FragmentManager
erlauben, Ihre FragmentTransaction
-Seite richtig auszuführen, insbesondere wenn sie im Backstack ausgeführt wird und Animationen und Übergänge ausführt. Wenn Sie das Flag aktivieren, werden bei der gleichzeitigen Ausführung mehrerer Transaktionen keine Zwischenfragmente (d.h. solche, die hinzugefügt und dann sofort ersetzt werden) durch Lebenszyklusänderungen geleitet und es werden keine Animationen oder Übergänge ausgeführt. Dieses Flag wirkt sich sowohl auf die anfängliche Ausführung der Transaktion als auch auf die Rückgängigmachung der Transaktion mit popBackStack()
aus.
Fragmente hinzufügen und entfernen
Wenn Sie einem FragmentManager
ein Fragment hinzufügen möchten, rufen Sie add()
auf. Diese Methode empfängt die ID des containers für das Fragment sowie den Klassennamen des Fragments, das Sie hinzufügen möchten. Das hinzugefügte Fragment wird in den Status RESUMED
verschoben. Wir empfehlen dringend, dass der Container ein FragmentContainerView
ist, der Teil der Ansichtshierarchie ist.
Wenn Sie ein Fragment vom Host entfernen möchten, rufen Sie remove()
auf und übergeben Sie eine Fragmentinstanz, die über findFragmentById()
oder findFragmentByTag()
aus dem Fragmentmanager abgerufen wurde.
Wenn die Ansicht des Fragments zuvor einem Container hinzugefügt wurde, wird sie an dieser Stelle aus dem Container entfernt. Das entfernte Fragment wird in den Status DESTROYED
verschoben.
Mit replace()
können Sie ein vorhandenes Fragment in einem Container durch eine Instanz einer neuen von Ihnen bereitgestellten Fragmentklasse ersetzen. Das Aufrufen von replace()
entspricht dem Aufrufen von remove()
mit einem Fragment in einem Container und dem Hinzufügen eines neuen Fragments zu diesem Container.
Das folgende Code-Snippet zeigt, wie Sie ein Fragment durch ein anderes ersetzen:
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();
In diesem Beispiel ersetzt eine neue Instanz von ExampleFragment
das Fragment, das sich derzeit im durch R.id.fragment_container
angegebenen Layoutcontainer befindet.
Standardmäßig werden die in einer FragmentTransaction
vorgenommenen Änderungen nicht dem Rückstapel hinzugefügt. Um diese Änderungen zu speichern, können Sie auf dem FragmentTransaction
die Taste addToBackStack()
drücken. Weitere Informationen finden Sie unter Fragment-Manager.
Commit ist asynchron
Durch den Aufruf von commit()
wird die Transaktion nicht sofort ausgeführt. Stattdessen wird die Transaktion so geplant, dass sie sobald wie möglich im Haupt-UI-Thread ausgeführt wird. Bei Bedarf können Sie jedoch commitNow()
aufrufen, um die Fragmenttransaktion sofort in Ihrem UI-Thread auszuführen.
commitNow
ist nicht mit addToBackStack
kompatibel. Alternativ können Sie alle ausstehenden FragmentTransactions
-Anfragen, die über commit()
-Anrufe gesendet wurden und noch nicht ausgeführt wurden, mit executePendingTransactions()
ausführen. Dieser Ansatz ist mit addToBackStack
kompatibel.
Für die meisten Anwendungsfälle reicht commit()
aus.
Die Reihenfolge der Operationen ist wichtig
Die Reihenfolge, in der Sie Vorgänge innerhalb einer FragmentTransaction
ausführen, ist wichtig, insbesondere bei Verwendung von setCustomAnimations()
. Mit dieser Methode werden die angegebenen Animationen auf alle nachfolgenden Fragmentvorgänge angewendet.
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()
Lebenszyklus des Fragments begrenzen
FragmentTransactions
kann sich auf den Lebenszyklusstatus einzelner Fragmente auswirken, die im Rahmen der Transaktion hinzugefügt wurden. Beim Erstellen eines FragmentTransaction
legt setMaxLifecycle()
einen maximalen Status für das angegebene Fragment fest. ViewPager2
verwendet beispielsweise setMaxLifecycle()
, um die Fragmente außerhalb des Bildschirms auf den Status STARTED
zu beschränken.
Ansichten des Fragments ein- und ausblenden
Mit den FragmentTransaction
-Methoden show()
und hide()
können Sie die Ansicht der Fragmente ein- und ausblenden, die einem Container hinzugefügt wurden.
Mit diesen Methoden wird die Sichtbarkeit der Ansichten des Fragments festgelegt, ohne den Lebenszyklus des Fragments zu beeinflussen.
Sie müssen zwar keine Fragmenttransaktion verwenden, um die Sichtbarkeit der Ansichten in einem Fragment umzuschalten, aber diese Methoden sind nützlich, wenn Änderungen am Sichtbarkeitsstatus mit Transaktionen im Backstack verknüpft werden sollen.
Fragmente anhängen und trennen
Mit der Methode FragmentTransaction
wird das Fragment von der Benutzeroberfläche getrennt, wodurch die Ansichtshierarchie zerstört wird.detach()
Das Fragment bleibt im selben Status (STOPPED
), in dem es auf den Backstack gelegt wurde.
Das Fragment wurde also aus der Benutzeroberfläche entfernt, wird aber weiterhin vom Fragmentmanager verwaltet.
Mit der Methode attach()
wird ein Fragment, von dem es zuvor getrennt wurde, wieder angehängt.
Dadurch wird die Ansichtshierarchie neu erstellt, an die Benutzeroberfläche angehängt und angezeigt.
Da ein FragmentTransaction
als einzelner atomarer Vorgang behandelt wird, heben sich Aufrufe von detach
und attach
für dieselbe Fragmentinstanz in derselben Transaktion effektiv auf. So wird verhindert, dass die Benutzeroberfläche des Fragments zerstört und sofort neu erstellt wird. Verwenden Sie separate Transaktionen, getrennt durch executePendingOperations()
, wenn Sie commit()
verwenden, um ein Fragment zu lösen und dann sofort wieder anzuhängen.