Nawigacja 3 to zasadnicza zmiana w sposobie, w jaki Jetpack Compose obsługuje stan nawigacji, i oferuje znaczące zalety architektoniczne w porównaniu z Nawigacją 2.
Poznaj zmiany w architekturze i kroki wymagane do migracji aplikacji Wear Compose z Nawigacji 2 do Nawigacji 3.
Główne zalety Nawigacji 3
- Bezpośrednia kontrola stosu wstecznego:
NavBackStackto zasadniczo tylko modyfikowalna lista obiektówNavKeyreprezentujących historię ekranów odwiedzonych przez użytkownika. Możesz ją kontrolować tak samo jak każdą inną listę KotlinMutableList(add,removeLast,clear). Możesz bezpośrednio manipulować listą, aby wykonywać działania związane z nawigacją, takie jak dodawanie klucza, aby przejść dalej lub usuwanie klucza, aby wrócić. - Projekt oparty na Compose: stos wsteczny jest modelowany jako standardowy stan obserwowalny. Modyfikowanie historii nawigacji działa dokładnie tak samo jak aktualizowanie dowolnego innego stanu Compose, automatycznie wywołując ponowne komponowanie w celu wyświetlenia bieżącego ekranu.
- Domyślnie bezpieczne typy: trasy oparte na ciągach znaków są całkowicie wyeliminowane. Nawigacja wykorzystuje serializowalne obiekty danych i klasy danych.
- Oddzielone prezentacje (strategie scen): warstwa przejścia interfejsu
(
NavDisplayiSwipeDismissableSceneStrategy) jest całkowicie oddzielona od śledzenia stanu (NavBackStack), co umożliwia prostszą integrację wbudowanych przejść nawigacji Wear OS.
Kroki migracji
1. Zaktualizuj zależności
Usuń starą zależność androidx.wear.compose:compose-navigation i dodaj nowe podzielone zależności Nawigacji 3 wraz z obsługą serializacji Kotlin.
Usuń:
implementation("androidx.wear.compose:compose-navigation:...")
Dodaj:
implementation("androidx.navigation3:navigation3-runtime:...") // State logic
implementation("androidx.navigation3:navigation3-ui:...") // Display logic
implementation("androidx.wear.compose:compose-navigation3:...") // Wear gestures
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:...") // Requires compiler plugin
2. Zaktualizuj miejsca docelowe, aby zaimplementować NavKey
W Nawigacji 2 do routingu można było używać ciągów znaków lub obiektów ogólnych. W
Nawigacji 3 musisz zaimplementować interfejs znacznika NavKey i
oznaczyć każdy obiekt ekranu adnotacją @Serializable.
Dlaczego to jest wymagane? Aby można było zapisać i
przywrócić stos wsteczny po śmierci procesu, bazowy navigation3-runtime używa
kotlinx-serialization do serializacji stanu.
Przed (Nawigacja 2 – ogólne trasy bezpieczne pod względem typów):
sealed class Nav2Screen { data object Landing : Nav2Screen() data object List : Nav2Screen() }
Po (Nawigacja 3 – NavKey + Serializable):
@Serializable sealed interface MigrationScreen : NavKey { @Serializable data object Landing : MigrationScreen @Serializable data object List : MigrationScreen }
3. Zastąp logikę routingu (NavController na NavBackStack)
Zastąp NavController elementem NavBackStack zainicjowanym za pomocą
rememberNavBackStack. Musisz też utworzyć instancję the
SwipeDismissableSceneStrategy specjalnie dla Wear OS.
Przed (Nawigacja 2):
val navController = rememberSwipeDismissableNavController()
Po (Nawigacja 3):
val backStack = rememberNavBackStack(MigrationScreen.Landing as NavKey) val strategy = rememberSwipeDismissableSceneStrategy<NavKey>()
4. Zastąp NavHost elementem NavDisplay i DSL entryProvider
Kontener NavHost i jego wewnętrzny konstruktor composable("route") { ... }
DSL są zastępowane przez NavDisplay i entryProvider {
entry<Key> { ... } } DSL.
Przed (Nawigacja 2):
SwipeDismissableNavHost(navController = navController, startDestination = "menu") { composable("menu") { GreetingScreen( onShowList = { navController.navigate("list") } ) } composable("list") { ListScreen() } }
Po (Nawigacja 3):
NavDisplay( backStack = backStack, sceneStrategies = listOf(strategy), entryProvider = entryProvider { entry<MigrationScreen.Landing> { GreetingScreen( onShowList = { backStack.add(MigrationScreen.List) } ) } entry<MigrationScreen.List> { ListScreen() } } )