W następnych sekcjach opisaliśmy strategie zapisywania stosu i zapisywania stanu powiązanego z elementami w stosie.
Zapisz stos wywołań
Zapewnienie spójności stanu nawigacji w aplikacji w różnych zdarzeniach cyklu życia, w tym w przypadku zmian konfiguracji i zakończenia procesu, jest kluczowe dla zapewnienia dobrego wrażenia korzystania z aplikacji. W Nawigacji 3 masz kontrolę nad warstwą wsteczną, więc nie ma ścisłych wytycznych dotyczących jej tworzenia ani zapisywania. Nawigacja 3 oferuje jednak wygodną metodę, która umożliwia zapisanie ścieżki wstecz:rememberNavBackStack
.
Używaj klawisza rememberNavBackStack
Funkcja kompozytowa rememberNavBackStack
została zaprojektowana tak, aby tworzyć warstwę pośrednią, która zachowuje trwałość pomimo zmian konfiguracji i zakończenia działania procesu.
Aby rememberNavBackStack
działał prawidłowo, każdy klucz w grupie musi spełniać określone wymagania:
- Zaimplementuj interfejs
NavKey
: każdy klucz w grupie poprzednich kluczy musi implementować interfejsNavKey
. Jest to interfejs znacznika, który sygnalizuje bibliotece, że klucz można zapisać. - Zaimplementuj adnotację
@Serializable
: oprócz zaimplementowaniaNavKey
klasy i obiekty kluczy muszą być oznaczone adnotacją@Serializable
.
Ten fragment kodu pokazuje prawidłową implementację funkcji rememberNavBackStack
:
@Serializable data object Home : NavKey @Composable fun NavBackStack() { val backStack = rememberNavBackStack(Home) }
Alternatywa: przechowywanie w ViewModel
Innym sposobem zarządzania stosem wstecz jest przechowywanie go w ViewModel
.
Aby zapewnić trwałość danych po śmierci procesu przy użyciu usługi ViewModel
lub innego niestandardowego miejsca do przechowywania, musisz:
- Upewnij się, że klucze można zserializować: podobnie jak w przypadku
rememberNavBackStack
, klucze nawigacyjne muszą być możliwe do zserializowania. - Ręczne zarządzanie serializacją i deserializacją: musisz ręcznie zapisać serializowane reprezentacje poszczególnych kluczy w trwałym miejscu przechowywania i zapisać je w tym samym miejscu (np.
SharedPreferences
, bazy danych lub pliku) podczas przełączania aplikacji na tło lub przywracania.
Ograniczenie zakresu do ViewModel
sNavEntry
ViewModels
służą do zachowania stanu związanego z interfejsem podczas zmian konfiguracji, takich jak obracanie ekranu. Domyślnie ViewModels
są ograniczone do najbliższego ViewModelStoreOwner
, którym zwykle jest Activity
lub Fragment
.
Możesz jednak ograniczyć zakres ViewModel
do konkretnego NavEntry
(czyli konkretnego ekranu lub miejsca docelowego) w grupie elementów na poprzednim poziomie, a nie do wszystkich elementów tej grupy.Activity
Dzięki temu stan ViewModel
jest zachowany tylko wtedy, gdy ten konkretny element NavEntry
znajduje się na stosie, a usuwany jest, gdy NavEntry
zostaje usunięty.
Biblioteka dodatków androidx.lifecycle:lifecycle-viewmodel-navigation3
udostępnia NavEntryDecorator
, która ułatwia to zadanie. Ten dekorator udostępnia element ViewModelStoreOwner
dla każdego elementu NavEntry
. Gdy utworzysz ViewModel
w ramach treści NavEntry
(np. używając viewModel()
w sekcji Redagowanie), zostanie on automatycznie ograniczony do klucza NavEntry
w bieżącym stosie. Oznacza to, że ViewModel
jest tworzony, gdy NavEntry
jest dodawany do stosu, i czyszczony, gdy jest usuwany.
Aby użyć NavEntryDecorator
do określenia zakresu ViewModel
w przypadku NavEntry
, wykonaj te czynności:
- Dodaj zależność
androidx.lifecycle:lifecycle-viewmodel-navigation3
do plikuapp/build.gradle.kts
. - Dodaj
rememberSavedStateNavEntryDecorator()
do listyentryDecorators
podczas tworzeniaNavDisplay
. - Dodaj innych dekoratorów do
NavDisplay
.
NavDisplay( entryDecorators = listOf( // Add the default decorators for managing scenes and saving state rememberSceneSetupNavEntryDecorator(), rememberSavedStateNavEntryDecorator(), // Then add the view model store decorator rememberViewModelStoreNavEntryDecorator() ), backStack = backStack, entryProvider = entryProvider { }, )