Nawigacja określa sposób poruszania się użytkowników po aplikacji. Użytkownicy wchodzą w interakcje z elementami interfejsu, zwykle przez ich klikanie lub dotykanie, a aplikacja reaguje, 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
Wygodne modelowanie tego zachowania polega na zastosowaniu zbioru treści. Gdy użytkownik przechodzi do nowych treści, są one przesuwane na wierzch stosu. Gdy powrócą do tej zawartości, zostanie ona usunięta ze stosu i wyświetli się poprzednia zawartość. W terminologii nawigacji ten zestaw nazywany jest zwykle zestawem poprzednich stron, ponieważ zawiera treści, do których użytkownik może wrócić.

Tworzenie ścieżki wstecznej
W wersji Nawigacja 3 stos wsteczny nie zawiera treści. Zamiast tego zawiera odwołania do treści, czyli klucze. Klucze mogą być dowolnego typu, ale zazwyczaj są to proste, serializowane klasy danych. Korzystanie z odwołań zamiast treści ma te zalety:
- Łatwo się po nim poruszać, przesuwając elementy na wyższy poziom.
- Dopóki klucze można zserializować, można zapisać stos w trwałym miejscu przechowywania, co pozwoli mu przetrwać zmiany konfiguracji i zakończenie procesu. Jest to ważne, ponieważ użytkownicy oczekują, że mogą opuścić Twoją aplikację, wrócić do niej później i wziąć ją od miejsca, w którym ją opuścili, z tymi samymi treściami. Więcej informacji znajdziesz w artykule Zachowywanie historii wywołań.
Ważną koncepcją w interfejsie Navigation 3 API jest to, że masz kontrolę nad stosem wstecznym. Biblioteka:
- Oczekuje, że zespół z poziomu poprzedniego będzie mieć stan
List<T>
, gdzieT
to typ zespołu z poziomu poprzedniegokeys
. Możesz użyćAny
lub podać własne klucze o bardziej ścisłym typie. Gdy widzisz terminy „push” lub „pop”, oznacza to, że implementacja polega na dodawaniu lub usuwaniu elementów z końca listy. - Obserwuje stos i odzwierciedla jego stan w interfejsie użytkownika za pomocą elementu
NavDisplay
.
Ten przykład pokazuje, jak utworzyć klucze i stół z elementami do cofnięcia oraz jak zmodyfikować ten stół w odpowiedzi na zdarzenia związane z przeglądaniem treści przez 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 w treści
Treści są modelowane w Nawigacji 3 za pomocą klasy NavEntry
, która zawiera funkcję składającą się z elementów. Reprezentuje miejsce docelowe, czyli 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 – informacje o treści. Te metadane mogą być odczytywane przez obiekty kontenera, takie jak NavDisplay
, aby pomóc im zdecydować, jak wyświetlić zawartość NavEntry
. Metadanych można na przykład używać do zastępowania domyślnych animacji w przypadku konkretnego NavEntry
. NavEntry
metadata
to mapa kluczy String
na wartości Any
, która zapewnia wszechstronne przechowywanie danych.
Aby przekształcić key
w NavEntry
, utwórz entryProvider
. To funkcja, która przyjmuje key
i zwraca NavEntry
dla tego key
. Jest on zwykle definiowany jako parametr lambda podczas tworzenia NavDisplay
.
Istnieją 2 sposoby tworzenia entryProvider
: bezpośrednio za pomocą funkcji lambda lub za pomocą języka entryProvider
DSL.
bezpośrednie tworzenie funkcji entryProvider
,
Funkcję entryProvider
zazwyczaj tworzy się za pomocą instrukcji when
, z odgałęziami 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żyj DSL entryProvider
Dzięki językowi entryProvider
DSL możesz uprościć funkcję lambda, ponieważ nie musisz testować każdego typu klucza i tworzyć dla każdego z nich NavEntry
.
W tym celu użyj funkcji konstruktora entryProvider
. Obejmuje ono też domyślne zachowanie zastępcze (zwracanie 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 w fragmentach kodu:
entry
służy do definiowaniaNavEntry
o danym typie i z możliwością składania treści.entry
przyjmuje parametrmetadata
, aby ustawićNavEntry.metadata
Wyświetlanie stosu elementów do tyłu
Stos wstecz reprezentuje stan nawigacji w aplikacji. Gdy zmienia się kolejność elementów w grupie elementów wstecz, interfejs aplikacji powinien odzwierciedlać nowy stan tej grupy. W ramach Nawigacji 3 komponentNavDisplay
obserwuje stos i odpowiednio aktualizuje interfejs. Utwórz go z tymi parametrami:
- Powrót do sterowania – powinien mieć typ
SnapshotStateList<T>
, gdzieT
to typ kluczy sterowania. Jest to obserwowalna wartośćList
, która po zmianie powoduje przekształcenie wartościNavDisplay
. entryProvider
, aby zamienić klucze w grupie poprzednich elementów naNavEntry
.- Opcjonalnie podaj w parametrze
onBack
funkcję lambda. Jest wywoływany, gdy użytkownik wywoła zdarzenie wstecz.
Z poniższego przykładu dowiesz się, 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 NavEntry
w grupie warstw w układzie z jednym panelem. Na poniższym nagraniu widać uruchomioną aplikację:

NavDisplay
zachowanie domyślne z 2 miejscami docelowymi.Podsumowanie
Ten diagram pokazuje, jak dane przepływają między różnymi obiektami w ramach funkcji Nawigacja 3:

Zdarzenia dotyczące nawigacji inicjują zmiany. Klucze są dodawane do stosu lub usuwane z niego w odpowiedzi na interakcje użytkownika.
Zmiana stanu stosu wywołuje pobieranie treści.
NavDisplay
(element składany, który renderuje stos wsteczny) obserwuje stos wsteczny. W domyślnej konfiguracji wyświetla ona najwyższy element wstecznej ścieżki wywołań w układzie z jednym panelem. Gdy zmienia się górny klucz w zbiorze,NavDisplay
używa tego klucza do żądania odpowiedniej treści od dostawcy danych.Dostawca danych dostarcza treści. Dostawca danych wejściowych to funkcja, która rozwiązuje klucz na
NavEntry
. Po otrzymaniu klucza odNavDisplay
dostawca danych udostępnia powiązanyNavEntry
, który zawiera zarówno klucz, jak i treści.Treści są wyświetlane.
NavDisplay
otrzymujeNavEntry
i wyświetla zawartość.