Na stan fragmentu mogą wpływać różne operacje systemu Android. Aby mieć pewność, że stan użytkownika zostanie zapisany, platforma Androida automatycznie zapisuje i przywraca fragmenty oraz tylny stos. Dlatego musisz , aby upewnić się, że wszystkie dane we fragmencie również zostaną zapisane i przywrócone.
W poniższej tabeli przedstawiono operacje, które powodują utratę fragmentu oraz tego, czy różne stany utrwalają się w nich zmian. Typy stanów wymienione w tabeli:
- Zmienne: zmienne lokalne we fragmencie.
- Stan widoku: dowolne dane, które należą do co najmniej jednego widoku danych we fragmencie.
- SavedState: dane właściwe dla tej instancji fragmentu, które powinny zostać zapisane
w usłudze
onSaveInstanceState()
. - NonConfig: dane pobrane ze źródła zewnętrznego, takiego jak serwer lub lokalny. lub dane utworzone przez użytkowników, które są wysyłane na serwer po zatwierdzeniu.
Zmienne często są traktowane tak samo jak SavedState, ale parametr w poniższej tabeli przedstawiono rozróżnienie między tymi dwoma elementami, aby zademonstrować efekt różnych operacji na każdym z nich.
Operacja | Zmienne | Stan widoku danych | SavedState | Brak konfiguracji |
---|---|---|---|---|
Dodano do tylnego stosu | ✓ | ✓ | x | ✓ |
Zmiana konfiguracji | x | ✓ | ✓ | ✓ |
Proces śmierci/wypoczynku | x | ✓ | ✓ | ✓* |
Usunięto, nie dodano do tylnego stosu | x | x | x | x |
Host zakończony | x | x | x | x |
* Stan NonConfig może być zachowany przez śmierć procesu za pomocą metody Moduł Saved State dla modelu ViewModel.
Tabela 1. Różne operacje destrukcyjne na fragmenty i ich skutki w różnych typach stanów.
Przeanalizujmy konkretny przykład. Weźmy np. ekran, który generuje
losowy ciąg znaków, wyświetla go w polu TextView
oraz udostępnia opcję edycji
przed wysłaniem wiadomości do znajomego:
W tym przykładzie załóżmy, że po naciśnięciu przez użytkownika przycisku edycji
aplikacja wyświetla widok EditText
, w którym użytkownik może edytować wiadomość. Jeśli
użytkownik kliknie ANULUJ, widok EditText
powinien zostać wyczyszczony
widoczność ustawiona na View.GONE
. Taka
cały ekran może wymagać zarządzania czterema elementami danych, by zapewnić płynne
funkcje:
Dane | Typ | Typ stanu | Opis |
---|---|---|---|
seed |
Long |
Brak konfiguracji | ziarno używane do losowego generowania nowego dobrego działania. Wygenerowany, gdy
gdy zostanie utworzony element ViewModel . |
randomGoodDeed |
String |
SavedState + zmienna | Wygenerowany podczas tworzenia fragmentu po raz pierwszy.
Plik randomGoodDeed jest zapisywany, aby użytkownicy widzieli
ten sam losowy dobry czyn nawet po śmierci procesowej,
rekreacji. |
isEditing |
Boolean |
SavedState + zmienna | Flaga wartości logicznej ustawiona na true , gdy użytkownik rozpoczyna edytowanie.
Plik isEditing zostanie zapisany, aby zapewnić, że część edytacyjna
ekran pozostaje widoczny po odtworzeniu fragmentu. |
Edytowany tekst | Editable |
Wyświetl stan (należący do: EditText ) |
Edytowany tekst w widoku EditText .
Widok EditText zapisuje ten tekst, aby zapewnić użytkownikowi
trwające zmiany nie zostaną utracone. |
Tabela 2. Wymagana jest aplikacja do generowania losowych tekstów.
W sekcjach poniżej znajdziesz informacje o tym, jak prawidłowo zarządzać stanem swoich danych za pomocą niszczycielskich działań.
Wyświetl stan
Wyświetlenia odpowiadają za zarządzanie własnym stanem. Na przykład, gdy plik
akceptuje dane wejściowe użytkownika, za zapisywanie i przywracanie widoku odpowiada jego zakres
które pozwalają obsługiwać zmiany konfiguracji. Wszystkie platformy Androida dostarczane przez platformę
widoki mają własną implementację tagów onSaveInstanceState()
oraz
onRestoreInstanceState()
, więc nie musisz zarządzać stanem wyświetlenia w
we fragmencie.
Na przykład w poprzednim scenariuszu edytowany ciąg znaków jest przechowywany w
EditText
EditText
wie,
wartość wyświetlanego tekstu oraz inne szczegóły, takie jak
na początku i na końcu dowolnego zaznaczonego tekstu.
Widok wymaga identyfikatora, aby zachować stan. Ten identyfikator musi być unikalny w obrębie a także ich hierarchię widoków. Widoki bez identyfikatora nie mogą zachować w swoim stanie.
<EditText android:id="@+id/good_deed_edit_text" android:layout_width="match_parent" android:layout_height="wrap_content" />
Jak wspomnieliśmy w tabeli 1, widoki danych zapisują i przywracają ViewState
przez
wszystkich operacji, które nie spowodują usunięcia fragmentu ani zniszczenia hosta.
SavedState
Fragment odpowiada za zarządzanie niewielkimi liczbami stanu dynamicznego
są integralną częścią działania fragmentu. Możesz zachować
uporządkowanych danych za pomocą
Fragment.onSaveInstanceState(Bundle)
Podobne do
Activity.onSaveInstanceState(Bundle)
dane umieszczone w pakiecie są przechowywane dzięki zmianom konfiguracji
i przetwarzać śmierć i reprodukcję. Jest dostępny we fragmencie
onCreate(Bundle)
,
onCreateView(LayoutInflater, ViewGroup, Bundle)
,
oraz
onViewCreated(View, Bundle)
.
Kontynuując poprzedni przykład: randomGoodDeed
jest aktem, który jest
wyświetlanej użytkownikowi, a isEditing
to flaga określająca, czy
powoduje wyświetlanie lub ukrywanie elementu EditText
. Zapisany stan powinien być
istniało przy użyciu funkcji onSaveInstanceState(Bundle)
, jak widać w tym przykładzie
przykład:
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); }
Aby przywrócić stan w funkcji onCreate(Bundle)
, pobierz zapisaną wartość z
pakiet:
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(); } }
Jak wspomniano w tabeli 1, zmienne są zachowywane, gdy parametr jest umieszczany na stosie wstecznym. Traktowanie ich jako zapisanych utrwalają się podczas wszystkich niszczycielskich operacji.
Brak konfiguracji
Dane spoza konfiguracji powinny znajdować się poza fragmentem, np. w
ViewModel
. W poprzedniej
W przykładzie powyżej zdarzenie seed
(stan NonConfig) jest generowane w ViewModel
.
Logika utrzymywania stanu należy do 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; } }
Klasa ViewModel
z założenia zezwala na przetrwanie konfiguracji danych.
takich jak obrót ekranu, i pozostaje w pamięci,
na tylny stos. Po śmierci i rekreacji
obiekt ViewModel
jest odtworzony i generowany jest nowy element seed
. Dodanie
Moduł SavedState
do ViewModel
pozwala ViewModel
na zachowanie prostego stanu przez
śmierć i śmierć.
Dodatkowe materiały
Więcej informacji o zarządzaniu stanem fragmentu znajdziesz w tych artykułach: z dodatkowymi zasobami.
Ćwiczenia z programowania
- Ćwiczenie z programowania dotyczące komponentów uwzględniających cykl życia