Zapisywanie stanu z fragmentami

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:

aplikacja do generowania losowych tekstów, która przedstawia różne
            rodzaje stanu
Rysunek 1. Aplikacja do generowania losowych tekstu, która pokazuje, różnych typów stanu.

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

Przewodniki