Nawigacja opisuje sposób poruszania się użytkowników po aplikacji. Użytkownicy wchodzą w interakcje z elementami interfejsu, zwykle klikając je lub dotykając, a aplikacja odpowiada, wyświetlając nowe treści. Jeśli użytkownik chce wrócić do poprzednich treści, używa gestu cofania lub klika przycisk Wstecz.
Modelowanie stanu nawigacji
Wygodnym sposobem modelowania tego zachowania jest stos treści. Gdy użytkownik przechodzi dalej do nowych treści, są one umieszczane na górze stosu. Gdy użytkownik wróci z tej treści, zostanie ona usunięta ze stosu i wyświetli się poprzednia treść. W terminologii nawigacyjnej ten stos jest zwykle nazywany stosem wstecznym, ponieważ reprezentuje treści, do których użytkownik może wrócić.

Tworzenie listy wstecznej
W Navigation 3 lista wsteczna nie zawiera treści. Zamiast tego zawiera odniesienia do treści, zwane kluczami. Klucze mogą być dowolnego typu, ale zwykle są to proste, serializowane klasy danych. Używanie odwołań zamiast treści ma następujące zalety:
- Nawigacja jest prosta – wystarczy nacisnąć klawisze na tylnej części urządzenia.
- Dopóki klucze są serializowane, można zapisać stos wsteczny w pamięci trwałej, dzięki czemu przetrwa on zmiany konfiguracji i zakończenie procesu. Jest to ważne, ponieważ użytkownicy oczekują, że po opuszczeniu aplikacji i późniejszym powrocie do niej będą mogli kontynuować korzystanie z tych samych treści. Więcej informacji znajdziesz w artykule Zapisywanie listy poprzednich ekranów.
Kluczową koncepcją interfejsu Navigation 3 API jest to, że stos wsteczny należy do Ciebie. Biblioteka:
- Oczekuje, że stos wsteczny będzie kopią stanu
List<T>
, gdzieT
to typ stosu wstecznegokeys
. Możesz użyćAny
lub podać własne, bardziej szczegółowe klucze. Gdy zobaczysz terminy „push” lub „pop”, oznacza to, że w tle dodawane lub usuwane są elementy z końca listy. - Obserwuje stos wsteczny i odzwierciedla jego stan w interfejsie za pomocą
NavDisplay
.
W tym przykładzie pokazujemy, jak tworzyć klucze i stos wsteczny oraz modyfikować stos wsteczny w odpowiedzi na zdarzenia nawigacji użytkownika:
// Define keys that will identify content data object ProductList data class ProductDetail(val id: String) @Composable fun MyApp() { // Create a back stack, specifying the key the app should start with val backStack = remember { mutableStateListOf<Any>(ProductList) } // Supply your back stack to a NavDisplay so it can reflect changes in the UI // ...more on this below... // Push a key onto the back stack (navigate forward), the navigation library will reflect the change in state backStack.add(ProductDetail(id = "ABC")) // Pop a key off the back stack (navigate back), the navigation library will reflect the change in state backStack.removeLastOrNull() }
Rozwiązywanie kluczy do treści
Treści w Navigation 3 są modelowane za pomocą NavEntry
, czyli klasy zawierającej funkcję kompozycyjną. Reprezentuje miejsce docelowe – pojedynczy element treści, do którego użytkownik może przejść i z którego może wrócić.
NavEntry
może też zawierać metadane, czyli informacje o treści. Te metadane mogą być odczytywane przez obiekty kontenera, takie jak NavDisplay
, aby pomóc im zdecydować, jak wyświetlać zawartość NavEntry
. Metadane mogą na przykład służyć do zastępowania domyślnych animacji w przypadku konkretnego NavEntry
. NavEntry
metadata
to mapa String
kluczy do Any
wartości, która zapewnia wszechstronne przechowywanie danych.
Aby przekonwertować key
na NavEntry
, utwórz dostawcę wpisów. Jest to funkcja, która przyjmuje key
i zwraca NavEntry
dla tego key
. Zwykle jest on definiowany jako parametr lambda podczas tworzenia NavDisplay
.
Dostawcę wpisów można utworzyć na 2 sposoby: bezpośrednio tworząc funkcję lambda lub za pomocą języka DSL entryProvider
.
Bezpośrednie tworzenie funkcji dostawcy wpisów
Funkcję Entry Provider tworzy się zwykle za pomocą instrukcji when
, z gałęzią dla każdego klucza.
entryProvider = { key -> when (key) { is ProductList -> NavEntry(key) { Text("Product List") } is ProductDetail -> NavEntry( key, metadata = mapOf("extraDataKey" to "extraDataValue") ) { Text("Product ${key.id} ") } else -> { NavEntry(Unit) { Text(text = "Invalid Key: $it") } } } }
Używanie języka DSL entryProvider
entryProvider
DSL może uprościć funkcję lambda, ponieważ nie musisz testować każdego typu klucza ani tworzyć NavEntry
dla każdego z nich.
Użyj w tym celu funkcji entryProvider
. Obejmuje też domyślne zachowanie rezerwowe (zgłaszanie błędu), jeśli klucz nie zostanie znaleziony.
entryProvider = entryProvider { entry<ProductList> { Text("Product List") } entry<ProductDetail>( metadata = mapOf("extraDataKey" to "extraDataValue") ) { key -> Text("Product ${key.id} ") } }
Zwróć uwagę na te informacje:
entry
służy do definiowaniaNavEntry
o danym typie i zawartości, którą można łączyć.entry
akceptuje parametrmetadata
, aby ustawićNavEntry.metadata
Wyświetlanie stosu wstecznego
Stos wsteczny reprezentuje stan nawigacji w aplikacji. Za każdym razem, gdy zmienia się stos wsteczny, interfejs aplikacji powinien odzwierciedlać nowy stan stosu wstecznego. W Navigation 3 komponent NavDisplay
obserwuje stos wsteczny i odpowiednio aktualizuje interfejs. Utwórz go, podając te parametry:
- Lista wsteczna – powinna być typu
SnapshotStateList<T>
, gdzieT
to typ kluczy listy wstecznej. Jest to obserwowalnyList
, więc gdy się zmieni, spowoduje ponowne skomponowanieNavDisplay
. entryProvider
– przekształca klucze w stosie wstecznym wNavEntry
obiekty.- Opcjonalnie możesz podać funkcję lambda w parametrze
onBack
. Ta funkcja jest wywoływana, gdy użytkownik wywoła zdarzenie powrotu.
Poniższy przykład pokazuje, jak utworzyć NavDisplay
.
data object Home data class Product(val id: String) @Composable fun NavExample() { val backStack = remember { mutableStateListOf<Any>(Home) } NavDisplay( backStack = backStack, onBack = { backStack.removeLastOrNull() }, entryProvider = { key -> when (key) { is Home -> NavEntry(key) { ContentGreen("Welcome to Nav3") { Button(onClick = { backStack.add(Product("123")) }) { Text("Click to navigate") } } } is Product -> NavEntry(key) { ContentBlue("Product ${key.id} ") } else -> NavEntry(Unit) { Text("Unknown route") } } } ) }
Domyślnie NavDisplay
wyświetla najwyższy element NavEntry
na liście wstecznej w układzie z 1 panelem. Na tym nagraniu widać działanie aplikacji:

NavDisplay
domyślne działanie z 2 miejscami docelowymiPodsumowanie
Ten diagram pokazuje przepływ danych między różnymi obiektami w Nawigacji 3:

Zdarzenia nawigacji inicjują zmiany. Klucze są dodawane do stosu wstecznego lub z niego usuwane w odpowiedzi na interakcje użytkownika.
Zmiana stanu listy wstecznej powoduje pobranie treści. Funkcja
NavDisplay
(kompozycja, która renderuje stos wsteczny) obserwuje stos wsteczny. W konfiguracji domyślnej wyświetla ona najwyższy wpis z listy wstecznej w układzie z jednym panelem. Gdy zmieni się klucz u góry stosu wstecznego,NavDisplay
używa tego klucza, aby poprosić dostawcę wpisu o odpowiednie treści.Dostawca wpisu dostarcza treści Dostawca wpisu to funkcja, która przekształca klucz w wartość
NavEntry
. Po otrzymaniu klucza odNavDisplay
dostawca wpisu udostępnia powiązanyNavEntry
, który zawiera zarówno klucz, jak i treść.Treści są wyświetlane. Urządzenie
NavDisplay
odbieraNavEntry
i wyświetla treści.