W kolejnych sekcjach opisujemy strategie zapisywania listy wstecznej i przechowywania stanu powiązanego z elementami na tej liście.
Zapisywanie listy poprzednich ekranów
Zapewnienie, że stan nawigacji aplikacji jest zachowywany w różnych zdarzeniach cyklu życia, w tym w przypadku zmian konfiguracji i zakończenia procesu, ma kluczowe znaczenie dla wygody użytkowników. W Navigation 3 masz pełną kontrolę nad stosem wstecznym, więc nie ma ścisłych wytycznych dotyczących jego tworzenia ani zapisywania. Nawigacja 3 udostępnia jednak wygodną metodę, która zapewnia możliwość zapisania stosu wstecznego: rememberNavBackStack.
Używaj klawisza rememberNavBackStack
Funkcja z możliwością komponowania rememberNavBackStack służy do tworzenia stosu wstecznego, który zachowuje trwałość w przypadku zmian konfiguracji i zakończenia procesu.
Aby funkcja rememberNavBackStack działała prawidłowo, każdy klucz w stosie wstecznym musi spełniać określone wymagania:
- Zaimplementuj interfejs
NavKey: każdy klucz w stosie wstecznym musi implementować interfejsNavKey. Jest to interfejs znacznika, który sygnalizuje bibliotece, że klucz można zapisać. - Mieć adnotację
@Serializable: oprócz wdrożeniaNavKeyklasy i obiekty kluczowe muszą być oznaczone adnotacją@Serializable.
Poniższy fragment kodu pokazuje prawidłową implementację elementu rememberNavBackStack:
@Serializable data object Home : NavKey @Composable fun NavBackStack() { val backStack = rememberNavBackStack(Home) }
Alternatywa: przechowywanie w ViewModel
Innym sposobem zarządzania stosem wstecznym jest przechowywanie go w ViewModel.
Aby zapewnić trwałość danych po zakończeniu procesu podczas korzystania z usługi ViewModel lub dowolnej innej niestandardowej usługi pamięci masowej, musisz:
- Upewnij się, że klucze można serializować: podobnie jak w przypadku
rememberNavBackStack, klucze nawigacyjne muszą być serializowalne. - Ręczne obsługiwanie serializacji i deserializacji: odpowiadasz za ręczne zapisywanie w pamięci trwałej (np.
SharedPreferences, bazy danych lub pliku), gdy aplikacja przechodzi w tło lub jest przywracana.
Zakres od ViewModel s do NavEntry s
ViewModels służą do zachowywania stanu interfejsu w przypadku zmian konfiguracji, takich jak obracanie ekranu. Domyślnie ViewModels są ograniczone do najbliższego ViewModelStoreOwner, którym jest zwykle Activity lub Fragment.
Możesz jednak ograniczyć zakres ViewModel do konkretnego NavEntry (czyli konkretnego ekranu lub miejsca docelowego) na liście wstecznej, a nie do całego Activity. Dzięki temu stan elementu ViewModel jest zachowywany tylko wtedy, gdy ten konkretny element NavEntry jest częścią stosu wstecznego, i jest usuwany, gdy element NavEntry jest usuwany ze stosu.
Biblioteka dodatku androidx.lifecycle:lifecycle-viewmodel-navigation3 udostępnia NavEntryDecorator, który to ułatwia. Ten dekorator udostępnia ViewModelStoreOwner dla każdego NavEntry. Gdy utworzysz ViewModel w treści NavEntry (np. za pomocą viewModel() w funkcji Compose), zostanie on automatycznie ograniczony do klucza tego konkretnego NavEntry na stosie wstecznym. Oznacza to, że element ViewModel jest tworzony, gdy element NavEntry jest dodawany do stosu wstecznego, i usuwany, gdy jest z niego usuwany.
Aby używać NavEntryDecorator do określania zakresu ViewModel w NavEntry, wykonaj te czynności:
- Dodaj zależność
androidx.lifecycle:lifecycle-viewmodel-navigation3do plikuapp/build.gradle.kts. - Dodaj
rememberSaveableStateHolderNavEntryDecorator()do listyentryDecoratorspodczas tworzeniaNavDisplay. - Dodaj do
NavDisplayinne dekoratory.
NavDisplay( entryDecorators = listOf( // Add the default decorators for managing scenes and saving state rememberSaveableStateHolderNavEntryDecorator(), // Then add the view model store decorator rememberViewModelStoreNavEntryDecorator() ), backStack = backStack, entryProvider = entryProvider { }, )