Lo stato del frammento può essere influenzato da varie operazioni di sistema Android. Per garantire che lo stato dell'utente venga salvato, il framework Android salva e ripristina automaticamente i frammenti e il back stack. Pertanto, devi assicurarti che anche i dati nel frammento vengano salvati e ripristinati.
La tabella seguente illustra le operazioni che causano la perdita dello stato del frammento e indica se i vari tipi di stato rimangono invariati durante queste modifiche. I tipi di stato menzionati nella tabella sono i seguenti:
- Variabili: variabili locali nel frammento.
- Stato della visualizzazione: tutti i dati di proprietà di una o più visualizzazioni nel frammento.
- SavedState: i dati inerenti a questa istanza di frammento che devono essere salvati
in
onSaveInstanceState()
. - NonConfig: dati estratti da un'origine esterna, come un server o un repository locale, oppure dati creati dall'utente che vengono inviati a un server dopo l'commit.
Spesso le variabili vengono trattate come le SavedState, ma la tabella seguente distingue tra le due per dimostrare l'effetto delle varie operazioni su ciascuna.
Funzionamento | Variabili | Visualizza stato | SavedState | Non-configurazione |
---|---|---|---|---|
Aggiunto alla serie di app aperte precedenti | ✓ | ✓ | x | ✓ |
Modifica configurazione | x | ✓ | ✓ | ✓ |
Interruzione del processo/ricreazione | x | ✓ | ✓ | ✓* |
Rimozione non aggiunta all'elenco filtri precedente | x | x | x | x |
Host completato | x | x | x | x |
* Lo stato NonConfig può essere mantenuto dopo l'interruzione del processo utilizzando il modulo Stato salvato per ViewModel.
Tabella 1: varie operazioni distruttive dei frammenti e i relativi effetti su diversi tipi di stato.
Vediamo un esempio specifico. Prendiamo ad esempio una schermata che genera una stringa random, la mostra in un TextView
e offre la possibilità di modificarla prima di inviarla a un amico:
Per questo esempio, supponiamo che, quando l'utente preme il pulsante di modifica, l'app mostri una visualizzazione EditText
in cui l'utente può modificare il messaggio. Se l'utente fa clic su ANNULLA, la visualizzazione EditText
deve essere cancellata e la sua visibilità impostata su View.GONE
. Per garantire un'esperienza senza interruzioni, una schermata di questo tipo potrebbe richiedere la gestione di quattro dati:
Dati | Digitazione | Tipo di stato | Descrizione |
---|---|---|---|
seed |
Long |
Non-configurazione | Seed utilizzato per generare in modo casuale una nuova buona azione. Generato quando viene creato ViewModel . |
randomGoodDeed |
String |
SavedState + Variabile | Generato quando il frammento viene creato per la prima volta.
randomGoodDeed viene salvato per garantire che gli utenti vedano la stessa buona azione casuale anche dopo la morte o la ricreazione del processo. |
isEditing |
Boolean |
SavedState + variabile | Flag booleano impostato su true quando l'utente inizia la modifica.
isEditing viene salvato per garantire che la parte di modifica dello schermo rimanga visibile quando il frammento viene ricreato. |
Testo modificato | Editable |
Stato della visualizzazione (di proprietà di EditText ) |
Il testo modificato nella visualizzazione EditText .
La visualizzazione EditText salva questo testo per garantire che le modifiche in corso dell'utente
non vadano perse. |
Tabella 2: indica che deve essere gestita l'app per la generazione di testo casuale.
Le sezioni seguenti descrivono come gestire correttamente lo stato dei dati tramite operazioni distruttive.
Visualizza stato
Le viste sono responsabili della gestione del proprio stato. Ad esempio, quando una vista accetta l'input dell'utente, è responsabilità della vista salvare e ripristinare questo input per gestire le modifiche alla configurazione. Tutte le visualizzazioni fornite dal framework Android hanno la propria implementazione di onSaveInstanceState()
e onRestoreInstanceState()
, quindi non devi gestire lo stato della visualizzazione all'interno del tuo frammento.
Ad esempio, nello scenario precedente, la stringa modificata è contenuta in un
EditText
. Un EditText
conosce il valore del testo visualizzato, nonché altri dettagli, come l'inizio e la fine del testo selezionato.
Una vista ha bisogno di un ID per mantenere il proprio stato. Questo ID deve essere univoco all'interno del frammento e della relativa gerarchia di visualizzazione. Le visualizzazioni senza ID non possono mantenere il loro stato.
<EditText android:id="@+id/good_deed_edit_text" android:layout_width="match_parent" android:layout_height="wrap_content" />
Come indicato nella tabella 1, le visualizzazioni salvano e ripristinano il proprio ViewState
tramite tutte le operazioni che non rimuovono il frammento o distruggono l'host.
SavedState
Il frammento è responsabile della gestione di piccole quantità di stato dinamico
che sono parte integrante del funzionamento del frammento. Puoi conservare i dati serializzati facilmente utilizzando Fragment.onSaveInstanceState(Bundle)
.
Analogamente a
Activity.onSaveInstanceState(Bundle)
,
i dati inseriti nel bundle vengono conservati attraverso modifiche alla configurazione
ed elaborano la morte e la ricreazione e sono disponibili nei metodi
onCreate(Bundle)
,
onCreateView(LayoutInflater, ViewGroup, Bundle)
e
onViewCreated(View, Bundle)
del frammento.
Continuando con l'esempio precedente, randomGoodDeed
è il documento che viene visualizzato all'utente e isEditing
è un flag per determinare se il frammento mostra o nasconde EditText
. Questo stato salvato deve essere conservato utilizzando onSaveInstanceState(Bundle)
, come mostrato nell'esempio seguente:
Kotlin
override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putBoolean(IS_EDITING_KEY, isEditing) outState.putString(RANDOM_GOOD_DEED_KEY, randomGoodDeed) }
Java
@Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(IS_EDITING_KEY, isEditing); outState.putString(RANDOM_GOOD_DEED_KEY, randomGoodDeed); }
Per ripristinare lo stato in onCreate(Bundle)
, recupera il valore archiviato dal bundle:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) isEditing = savedInstanceState?.getBoolean(IS_EDITING_KEY, false) randomGoodDeed = savedInstanceState?.getString(RANDOM_GOOD_DEED_KEY) ?: viewModel.generateRandomGoodDeed() }
Java
@Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState != null) { isEditing = savedInstanceState.getBoolean(IS_EDITING_KEY, false); randomGoodDeed = savedInstanceState.getString(RANDOM_GOOD_DEED_KEY); } else { randomGoodDeed = viewModel.generateRandomGoodDeed(); } }
Come indicato nella tabella 1, tieni presente che le variabili vengono conservate quando il frammento viene inserito nella pila precedente. Il trattamento come stato salvato garantisce che rimangano invariati durante tutte le operazioni distruttive.
Non-configurazione
I dati NonConfig devono essere posizionati all'esterno del frammento, ad esempio in un ViewModel
. Nell'esempio precedente, in ViewModel
viene generato seed
(il nostro stato NonConfig).
La logica per mantenere lo stato è di proprietà di ViewModel
.
Kotlin
public class RandomGoodDeedViewModel : ViewModel() { private val seed = ... // Generate the seed private fun generateRandomGoodDeed(): String { val goodDeed = ... // Generate a random good deed using the seed return goodDeed } }
Java
public class RandomGoodDeedViewModel extends ViewModel { private Long seed = ... // Generate the seed private String generateRandomGoodDeed() { String goodDeed = ... // Generate a random good deed using the seed return goodDeed; } }
La classe ViewModel
consente intrinsecamente i dati di sopravvivere alle modifiche alla configurazione, come le rotazioni dello schermo, e rimane in memoria quando il frammento viene posizionato sullo stack posteriore. Dopo l'interruzione e la ricreazione del processo,
ViewModel
viene ricreato e viene generato un nuovo seed
. L'aggiunta di un modulo SavedState
al tuo ViewModel
consente a ViewModel
di mantenere uno stato semplice tramite l'interruzione e la ricreazione del processo.
Risorse aggiuntive
Per ulteriori informazioni sulla gestione dello stato del frammento, consulta le seguenti risorse aggiuntive.
Codelab
Guide
- Modulo stato salvato per il modello di visualizzazione
- Salvataggio degli stati dell'interfaccia utente