In fase di runtime, una FragmentManager
può aggiungere, rimuovere, sostituire ed eseguire altre azioni con frammenti in risposta all'interazione dell'utente. Ogni set di modifiche ai frammenti di cui esegui il commit è chiamato transazione e puoi specificare cosa fare all'interno della transazione utilizzando le API fornite dalla classe FragmentTransaction
. Puoi raggruppare più azioni in una singola transazione, ad esempio una transazione può aggiungere o sostituire più frammenti. Questo raggruppamento può essere utile quando sulla stessa schermata sono visualizzati più frammenti di pari livello, ad esempio con le visualizzazioni divise.
Puoi salvare ogni transazione in uno stack di sistema gestito da FragmentManager
, in modo che l'utente possa spostarsi a ritroso nelle modifiche ai frammenti, in modo simile a una navigazione a ritroso tra le attività.
Puoi ottenere un'istanza di FragmentTransaction
da FragmentManager
chiamando beginTransaction()
, come mostrato nell'esempio seguente:
Kotlin
val fragmentManager = ... val fragmentTransaction = fragmentManager.beginTransaction()
Java
FragmentManager fragmentManager = ... FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
L'ultima chiamata su ogni FragmentTransaction
deve eseguire il commit della transazione.
Gli indicatori di chiamata commit()
a FragmentManager
che indicano che tutte le operazioni sono state aggiunte alla transazione.
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();
Consenti il riordinamento delle modifiche dello stato dei frammenti
Ogni FragmentTransaction
deve utilizzare setReorderingAllowed(true)
:
Kotlin
supportFragmentManager.commit { ... setReorderingAllowed(true) }
Java
FragmentManager fragmentManager = ... fragmentManager.beginTransaction() ... .setReorderingAllowed(true) .commit();
Per compatibilità del comportamento, il flag di riordinamento non è attivo per impostazione predefinita.
Tuttavia, è necessario consentire a FragmentManager
di eseguire correttamente FragmentTransaction
, in particolare quando opera sullo stack posteriore ed esegue animazioni e transizioni. L'abilitazione del flag garantisce che, se vengono eseguite più transazioni contemporaneamente, eventuali frammenti intermedi (ad es. quelli aggiunti e poi immediatamente sostituiti) non subiscano modifiche del ciclo di vita né vengono eseguite animazioni o transizioni relative a questi elementi. Tieni presente che questo flag influisce sia sull'esecuzione iniziale della transazione sia sull'inversione della transazione con popBackStack()
.
Aggiunta e rimozione di frammenti
Per aggiungere un frammento a un FragmentManager
, chiama
add()
nella transazione. Questo metodo riceve l'ID del container per il frammento, nonché il nome della classe del frammento che vuoi aggiungere. Il frammento aggiunto viene spostato nello stato RESUMED
. Ti consigliamo vivamente di fare in modo che il contenitore sia un elemento FragmentContainerView
che fa parte della gerarchia delle visualizzazioni.
Per rimuovere un frammento dall'host, chiama remove()
e passa in un'istanza di frammento recuperata dalla gestione frammenti tramite findFragmentById()
o findFragmentByTag()
.
Se la visualizzazione del frammento è stata aggiunta in precedenza a un container, a questo punto viene rimossa dal container. Il frammento rimosso viene spostato
nello stato DESTROYED
.
Utilizza replace()
per sostituire un frammento esistente in un container con un'istanza di una nuova classe di frammenti da te fornita. Chiamare replace()
equivale a chiamare remove()
con un frammento in un container e ad aggiungere un nuovo frammento allo stesso container.
Il seguente snippet di codice mostra come sostituire un frammento con un altro:
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 questo esempio, una nuova istanza di ExampleFragment
sostituisce l'eventuale frammento che si trova attualmente nel contenitore di layout identificato da R.id.fragment_container
.
Per impostazione predefinita, le modifiche apportate in un FragmentTransaction
non vengono aggiunte
allo stack di backup. Per salvare queste modifiche, puoi chiamare
addToBackStack()
sul FragmentTransaction
. Per ulteriori informazioni, vedi Gestione frammenti.
Il commit è asincrono
La chiamata a commit()
non esegue immediatamente la transazione. Piuttosto, la transazione è pianificata per essere eseguita nel thread dell'interfaccia utente principale non appena è in grado di farlo. Se necessario, tuttavia, puoi chiamare commitNow()
per eseguire immediatamente la transazione del frammento nel thread dell'interfaccia utente.
Tieni presente che commitNow
non è compatibile con addToBackStack
. In alternativa,
puoi eseguire tutte le chiamate FragmentTransactions
in sospeso inviate da
commit()
chiamate non ancora eseguite chiamando executePendingTransactions()
. Questo approccio è compatibile con addToBackStack
.
Nella maggior parte dei casi d'uso, commit()
è tutto ciò di cui hai bisogno.
L'ordine delle operazioni è significativo
L'ordine in cui esegui le operazioni all'interno di un elemento FragmentTransaction
è significativo, in particolare quando utilizzi setCustomAnimations()
. Questo metodo applica le animazioni specificate a tutte le operazioni sui frammenti che le seguono.
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()
Limitare il ciclo di vita del frammento
FragmentTransactions
può influire sullo stato del ciclo di vita dei singoli
frammenti aggiunti nell'ambito della transazione. Quando crei un elemento
FragmentTransaction
,
setMaxLifecycle()
imposta uno stato massimo per il frammento specificato. Ad esempio, ViewPager2
utilizza setMaxLifecycle()
per limitare i frammenti fuori schermo allo stato STARTED
.
Mostrare e nascondere le visualizzazioni del frammento
Utilizza i metodi FragmentTransaction
show()
e
hide()
per mostrare e nascondere la visualizzazione dei frammenti aggiunti a un container.
Questi metodi impostano la visibilità delle viste del frammento senza influire sul ciclo di vita del frammento.
Sebbene non sia necessario utilizzare una transazione del frammento per attivare/disattivare la visibilità delle viste all'interno di un frammento, questi metodi sono utili nei casi in cui vuoi che le modifiche allo stato di visibilità vengano associate alle transazioni sullo stack di backup.
Collegamento e scollegamento di frammenti
Il metodo FragmentTransaction
detach()
scollega il frammento dall'interfaccia utente, distruggendone la gerarchia delle visualizzazioni. Il frammento
rimane nello stesso stato (STOPPED
) di quando viene inserito nello stack di backup.
Ciò significa che il frammento è stato rimosso dall'interfaccia utente, ma è ancora gestito dal gestore di frammenti.
Il metodo attach()
ricollega un frammento da cui è stato scollegato in precedenza.
In questo modo, la gerarchia delle visualizzazioni viene ricreata, collegata all'interfaccia utente e visualizzata.
Poiché FragmentTransaction
viene trattato come un singolo insieme atomico di operazioni, le chiamate a detach
e attach
sulla stessa istanza di frammento nella stessa transazione si annullano efficacemente a vicenda, evitando la distruzione e la riproduzione immediata dell'UI del frammento. Utilizza transazioni separate, separate da executePendingOperations()
se utilizzi commit()
, se vuoi scollegare e poi ricollegare immediatamente un frammento.