Ogni istanza Fragment
ha un proprio ciclo di vita. Quando un utente naviga e interagisce con la tua app, i tuoi frammenti passano attraverso vari stati durante il loro ciclo di vita, man mano che vengono aggiunti, rimossi ed entrano o escono dalla schermata.
Per gestire il ciclo di vita, Fragment
implementa
LifecycleOwner
, esponendo
un oggetto Lifecycle
a cui
puoi accedere tramite il
metodo
getLifecycle()
.
Ogni possibile stato Lifecycle
è rappresentato nell'enumerazione
Lifecycle.State
.
Creando Fragment
su Lifecycle
, puoi utilizzare le tecniche e le classi disponibili per gestire i cicli di vita con i componenti sensibili al ciclo di vita.
Ad esempio, potresti visualizzare la posizione del dispositivo sullo schermo
utilizzando un componente sensibile al ciclo di vita. Questo componente potrebbe
avviare automaticamente l'ascolto quando il frammento diventa attivo e interrompersi quando
il frammento passa a uno stato inattivo.
In alternativa all'utilizzo di un elemento LifecycleObserver
, la classe Fragment
include metodi di callback che corrispondono a ogni modifica nel ciclo di vita di un frammento. Questi includono
onCreate()
,
onStart()
,
onResume()
,
onPause()
,
onStop()
e
onDestroy()
.
La vista di un frammento ha un elemento Lifecycle
separato che viene gestito in modo indipendente
da quello dell'elemento Lifecycle
del frammento. I frammenti mantengono un elemento LifecycleOwner
per la loro visualizzazione, a cui è possibile accedere utilizzando getViewLifecycleOwner()
o getViewLifecycleOwnerLiveData()
.
Avere accesso all'elemento Lifecycle
della vista è utile nei casi in cui un componente sensibile al ciclo di vita debba eseguire operazioni solo mentre è presente la visualizzazione di un frammento, ad esempio osservare LiveData
che deve essere visualizzato solo sullo schermo.
Questo argomento illustra in dettaglio il ciclo di vita di Fragment
, spiegando alcune delle regole che determinano lo stato del ciclo di vita di un frammento e mostrando la relazione tra gli stati Lifecycle
e i callback del ciclo di vita del frammento.
Frammenti e gestore frammenti
Quando viene creata un'istanza di un frammento, inizia nello stato INITIALIZED
. Per consentire la transizione di un frammento per il resto del suo ciclo di vita, deve essere aggiunto a
FragmentManager
. L'elemento FragmentManager
è responsabile di determinare lo stato in cui si trova il frammento e di spostarlo in quello stato.
Oltre il ciclo di vita dei frammenti, FragmentManager
è anche responsabile del collegamento dei frammenti all'attività host e del loro scollegamento quando il frammento non è più in uso. La classe Fragment
ha due metodi di callback, onAttach()
e onDetach()
, che puoi sostituire per eseguire il lavoro quando si verifica uno di questi eventi.
Il callback onAttach()
viene richiamato quando il frammento è stato aggiunto a un FragmentManager
ed è associato alla sua attività host. A questo punto, il frammento è attivo e FragmentManager
ne gestisce lo stato del ciclo di vita. A questo punto, metodi FragmentManager
come
findFragmentById()
restituiscono questo frammento.
onAttach()
viene sempre chiamato prima di qualsiasi modifica dello stato del ciclo di vita.
Il callback onDetach()
viene richiamato quando il frammento è stato rimosso da un FragmentManager
e viene scollegato dall'attività host. Il frammento non è più attivo e non può più essere recuperato utilizzando findFragmentById()
.
onDetach()
viene sempre chiamato dopo qualsiasi modifica dello stato del ciclo di vita.
Tieni presente che questi callback non sono correlati ai metodi FragmentTransaction
attach()
e detach()
.
Per ulteriori informazioni su questi metodi, consulta
Transazioni relative ai frammenti.
Stati e callback del ciclo di vita dei frammenti
Nel determinare lo stato del ciclo di vita di un frammento, FragmentManager
considera quanto segue:
- Lo stato massimo di un frammento è determinato dal suo
FragmentManager
. Un frammento non può avanzare oltre lo stato del relativoFragmentManager
. - Nell'ambito di
FragmentTransaction
, puoi impostare uno stato massimo del ciclo di vita su un frammento utilizzandosetMaxLifecycle()
. - Lo stato del ciclo di vita di un frammento non può mai essere superiore al relativo padre. Ad esempio, un'attività o un frammento padre deve essere avviato prima dei relativi frammenti figlio. Allo stesso modo, i frammenti figlio devono essere arrestati prima del frammento o dell'attività padre.
La Figura 1 mostra ciascuno degli stati Lifecycle
del frammento e la loro correlazione con i callback del ciclo di vita del frammento e la vista Lifecycle
del frammento.
Man mano che un frammento progredisce nel suo ciclo di vita, si sposta in alto e in basso attraverso i suoi stati. Ad esempio, un frammento aggiunto alla parte superiore dello stack posteriore si sposta verso l'alto da CREATED
a STARTED
a RESUMED
. Al contrario, quando un frammento esce dallo stack posteriore, si sposta verso il basso attraverso questi stati, passando da RESUMED
a STARTED
a CREATED
e infine DESTROYED
.
Transizioni di stato verso l'alto
Durante lo spostamento verso l'alto degli stati del ciclo di vita, un frammento chiama prima il callback del ciclo di vita associato per il nuovo stato. Al termine di questo callback, il Lifecycle.Event
pertinente viene emesso per gli osservatori dal valore Lifecycle
del frammento, seguito dalla visualizzazione del frammento Lifecycle
, se ne è stata creata un'istanza.
Frammento CREATO
Quando il frammento raggiunge lo stato CREATED
, è stato aggiunto a un elemento FragmentManager
e il metodo onAttach()
è già stato chiamato.
Questo sarebbe il posto appropriato per ripristinare lo stato salvato associato al frammento stesso tramite SavedStateRegistry
del frammento.
Tieni presente che la vista del frammento non è stata creata in questo momento e qualsiasi stato associato alla vista del frammento deve essere ripristinato solo dopo la creazione della vista.
Questa transizione richiama il callback onCreate()
. Il callback riceve anche un argomento savedInstanceState
Bundle
contenente qualsiasi stato
salvato in precedenza da
onSaveInstanceState()
.
Tieni presente che savedInstanceState
ha un valore null
la prima volta che
il frammento viene creato, ma è sempre "non null" per le successive
creazioni, anche se non esegui l'override di onSaveInstanceState()
. Per ulteriori dettagli, consulta Salvataggio dello stato con i frammenti.
Frammento CREATO e visualizzazione INIZIALIZZATA
La visualizzazione del frammento Lifecycle
viene creata solo quando Fragment
fornisce un'istanza View
valida. Nella maggior parte dei casi, puoi utilizzare i costruttori di frammenti che utilizzano @LayoutId
, che aumenta automaticamente la visualizzazione al momento opportuno. Puoi anche eseguire l'override di onCreateView()
per gonfiare o creare la visualizzazione del frammento in modo programmatico.
Se e solo se viene creata un'istanza della visualizzazione del frammento con un valore View
non null, questo valore View
viene impostato sul frammento e può essere recuperato utilizzando getView()
. Il componente getViewLifecycleOwnerLiveData()
viene quindi aggiornato con la nuova INITIALIZED
LifecycleOwner
corrispondente alla visualizzazione del frammento. In questo momento viene chiamato anche il callback onViewCreated()
.
Questa è la posizione appropriata per impostare lo stato iniziale della visualizzazione, per iniziare a osservare le istanze LiveData
i cui callback aggiornano la visualizzazione del frammento e configurare gli adattatori su qualsiasi istanza RecyclerView
o ViewPager2
nella visualizzazione del frammento.
Frammento e visualizzazione CREATED
Una volta creata la vista del frammento, lo stato di visualizzazione precedente, se presente, viene ripristinato e il valore Lifecycle
della vista viene spostato allo stato CREATED
. Il proprietario del ciclo di vita della vista emette anche l'evento ON_CREATE
per i suoi osservatori. Qui devi ripristinare qualsiasi stato aggiuntivo
associato alla vista del frammento.
Questa transizione richiama anche il callback onViewStateRestored()
.
Frammento e visualizzazione AVVIATI
Ti consigliamo vivamente di collegare i componenti sensibili al ciclo di vita allo stato STARTED
di un frammento, in quanto questo stato garantisce che la visualizzazione del frammento sia disponibile, se ne è stata creata una, e che è possibile eseguire una FragmentTransaction
sull'elemento secondario FragmentManager
del frammento. Se la visualizzazione del frammento è diversa da null, la visualizzazione Lifecycle
del frammento viene spostata in STARTED
subito dopo che l'elemento Lifecycle
del frammento viene spostato in STARTED
.
Quando il frammento diventa STARTED
, viene richiamato il callback onStart()
.
Frammento e visualizzazione RIPRISTINATI
Quando il frammento è visibile, tutti gli effetti Animator
e Transition
sono stati completati e il frammento è pronto per l'interazione da parte dell'utente. L'elemento Lifecycle
del frammento passa allo stato RESUMED
e viene richiamato il callback onResume()
.
La transizione a RESUMED
è l'indicatore appropriato per indicare che ora l'utente è in grado di interagire con il frammento. I frammenti che non sono RESUMED
non devono impostare manualmente lo stato attivo sulle relative visualizzazioni o tentare di gestire la visibilità del metodo di inserimento.
Transizioni di stato verso il basso
Quando un frammento passa a uno stato del ciclo di vita inferiore, il
rilevante Lifecycle.Event
viene emesso per gli osservatori dalla visualizzazione Lifecycle
del frammento, se creata un'istanza,
seguita dall'Lifecycle
del frammento. Dopo che viene emesso un evento del ciclo di vita di un frammento, il frammento chiama il callback associato del ciclo di vita.
Frammento e visualizzazione AVVIATI
Quando l'utente inizia ad abbandonare il frammento e mentre il frammento è ancora visibile, gli elementi Lifecycle
per il frammento e per la sua visualizzazione vengono riportati allo stato STARTED
ed emettono l'evento ON_PAUSE
per i suoi osservatori. Il frammento richiama quindi il proprio callback onPause()
.
Frammento e visualizzazione CREATED
Quando il frammento non è più visibile, i Lifecycle
per il frammento e per la sua visualizzazione vengono spostati nello stato CREATED
ed emettono l'evento ON_STOP
per i rispettivi osservatori. Questa transizione di stato viene attivata non solo dall'interruzione dell'attività o del frammento padre, ma anche dal salvataggio dello stato da parte dell'attività o del frammento padre. Questo comportamento garantisce che l'evento ON_STOP
venga richiamato prima che lo stato del frammento venga salvato. In questo modo
l'evento ON_STOP
diventa l'ultimo punto in cui è possibile eseguire in sicurezza una
FragmentTransaction
sul file secondario FragmentManager
.
Come mostrato nella Figura 2, l'ordine del callback onStop()
e il salvataggio dello stato con onSaveInstanceState()
variano in base al livello API. Per tutti i livelli API precedenti all'API 28, onSaveInstanceState()
viene richiamato
prima del giorno onStop()
.
Per i livelli API 28 e successivi, l'ordine delle chiamate viene invertito.
Frammento CREATED e visualizzazione DESTROYED
Dopo che tutte le animazioni e le transizioni di uscita sono state completate e la vista del frammento è stata scollegata dalla finestra, la vista Lifecycle
del frammento viene spostata nello stato DESTROYED
ed emette l'evento ON_DESTROY
per i suoi osservatori. Il frammento richiama quindi il proprio callback onDestroyView()
. A questo punto, la vista del frammento ha raggiunto la fine del suo
ciclo di vita e
getViewLifecycleOwnerLiveData()
restituisce un valore null
.
A questo punto, tutti i riferimenti alla vista del frammento devono essere rimossi, consentendo la garbage collection della visualizzazione del frammento.
Frammento DISTRUTTO
Se il frammento viene rimosso o se FragmentManager
viene eliminato, l'elemento Lifecycle
del frammento viene spostato nello stato DESTROYED
e invia l'evento ON_DESTROY
ai relativi osservatori. Il frammento richiama quindi il proprio callback onDestroy()
. A questo punto, il frammento ha raggiunto la fine del suo ciclo di vita.
Risorse aggiuntive
Per saperne di più sul ciclo di vita dei frammenti, consulta le seguenti risorse aggiuntive.