In fase di esecuzione, un
FragmentManager
può aggiungere, rimuovere, sostituire ed eseguire altre azioni con i frammenti
in risposta all'interazione dell'utente. Ogni insieme di modifiche ai frammenti che committi è 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 sullo stesso schermo sono visualizzati più frammenti fratelli, ad esempio con le visualizzazioni divise.
Puoi salvare ogni transazione in uno stack di ritorno gestito da FragmentManager
, consentendo all'utente di tornare indietro tra le modifiche del frammento, in modo simile allo spostamento all'indietro 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 l'commit della transazione.
La chiamata commit()
indica a FragmentManager
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 del frammento
Ogni FragmentTransaction
deve utilizzare setReorderingAllowed(true)
:
Kotlin
supportFragmentManager.commit { ... setReorderingAllowed(true) }
Java
FragmentManager fragmentManager = ... fragmentManager.beginTransaction() ... .setReorderingAllowed(true) .commit();
Per garantire la compatibilità del comportamento, il flag di riordinamento non è abilitato per impostazione predefinita.
Tuttavia, è necessario consentire a FragmentManager
di eseguire correttamente il tuo FragmentTransaction
, in particolare quando opera nella pila posteriore ed esegue animazioni e transizioni. L'attivazione del flag garantisce che, se vengono eseguite più transazioni contemporaneamente, gli eventuali frammenti intermedi (ovvero quelli aggiunti e poi sostituiti immediatamente) non subiscano modifiche del ciclo di vita o non vengano eseguite le relative animazioni o transizioni. Tieni presente che questo flag influisce sia sull'esecuzione iniziale della transazione sia sull'annullamento della transazione con popBackStack()
.
Aggiunta e rimozione di frammenti
Per aggiungere un frammento a un FragmentManager
, chiama
add()
sulla transazione. Questo metodo riceve
l'ID del contenitore 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 utilizzare un contenitore
FragmentContainerView
che fa parte della gerarchia delle visualizzazioni.
Per rimuovere un frammento dall'host, chiama
remove()
,
passando un'istanza di frammento recuperata dal gestore
del frammento tramite findFragmentById()
o findFragmentByTag()
.
Se la vista del frammento è stata aggiunta in precedenza a un contenitore, a questo punto viene rimossa dal contenitore. Il frammento rimosso viene spostato
allo stato DESTROYED
.
Utilizza
replace()
per sostituire un frammento esistente in un contenitore con un'istanza di una
nuova classe di frammenti che fornisci. Chiamare replace()
equivale a chiamare remove()
con un frammento in un container e 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 il frammento, se presente, attualmente nel contenitore del layout identificato da R.id.fragment_container
.
Per impostazione predefinita, le modifiche apportate in un FragmentTransaction
non vengono aggiunte alla pila precedente. Per salvare queste modifiche, puoi chiamare
addToBackStack()
sul FragmentTransaction
. Per ulteriori informazioni, consulta
Gestione dei frammenti.
L'commit è asincrono
La chiamata al numero
commit()
non esegue immediatamente la transazione. La transazione è invece programmata per essere eseguita nel thread dell'interfaccia utente principale non appena sarà possibile. Se necessario, però, 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 attesa inviate da commit()
che non sono ancora state eseguite chiamando executePendingTransactions()
. Questo approccio è compatibile con addToBackStack
.
Per la 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
FragmentTransaction
è importante, in particolare quando utilizzi setCustomAnimations()
. Questo
metodo applica le animazioni specificate a tutte le operazioni sui frammenti successive.
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
FragmentTransaction
,
setMaxLifecycle()
imposta uno stato massimo per il frammento specificato. Ad esempio,
ViewPager2
utilizza
setMaxLifecycle()
per limitare i frammenti off-screen allo stato STARTED
.
Visualizzazione e occultamento delle visualizzazioni del frammento
Utilizza i metodi FragmentTransaction
show()
e
hide()
per mostrare e nascondere la visualizzazione dei frammenti aggiunti a un contenitore.
Questi metodi impostano la visibilità delle visualizzazioni 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 visualizzazioni all'interno di un frammento, questi metodi sono utili nei casi in cui vuoi che le modifiche allo stato di visibilità siano associate alle transazioni nello stack precedente.
Collegamento e scollegamento di frammenti
Il metodo FragmentTransaction
detach()
scollega il frammento dall'interfaccia utente, distruggendo la relativa gerarchia di visualizzazione. Il frammento rimane nello stesso stato (STOPPED
) di quando viene inserito nella pila posteriore.
Ciò significa che il frammento è stato rimosso dall'interfaccia utente, ma è ancora gestito dal gestore dei frammenti.
Il metodo
attach()
riattacca un frammento da cui era stato precedentemente scollegato.
Di conseguenza, la gerarchia delle visualizzazioni viene ricreata, collegata all'interfaccia utente e visualizzata.
Poiché un FragmentTransaction
viene trattato come un singolo insieme atomico di operazioni,
le chiamate sia a detach
che a attach
sulla stessa istanza di frammento nella stessa
transazione si annullano efficacemente a vicenda, evitando così la
distruzione e la ricreazione immediata dell'interfaccia utente del frammento. Utilizza transazioni separate, separate da executePendingOperations()
se utilizzi commit()
, se vuoi scollegare e ricollegare immediatamente un frammento.