Fragment-Transaktionen

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.