Ciclo di vita di un frammento

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 relativo FragmentManager.
  • Nell'ambito di FragmentTransaction, puoi impostare uno stato massimo del ciclo di vita su un frammento utilizzando setMaxLifecycle() .
  • 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.
Gli stati del ciclo di vita del frammento e la relativa relazione sia i callback del ciclo di vita del frammento che il ciclo di visualizzazione del frammento
Figura 1. Stati Lifecycle del frammento e la relativa relazione sia ai callback del ciclo di vita del frammento che alla visualizzazione Lifecycle del frammento.

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.

differenze di ordine delle chiamate per onStop() e onSaveInstanceState()
Figura 2. Differenze nell'ordine di chiamata per onStop() e onSaveInstanceState().

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.

Guide

Blog