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, wykonuje gest 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 3 nawigacji 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ć, naciskając klawisze.
- Dopóki klucze można zserializować, można zapisać stos w pamięci trwałej, 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ń.
Kluczową 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>
z archiwizowanym stanem migawki, 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 apek i odzwierciedla jego stan w interfejsie za pomocą
NavDisplay
.
Ten przykład pokazuje, jak utworzyć klucze i stół z elementami poprzednich poziomów oraz zmodyfikować ten stół w odpowiedzi na zdarzenia związane z przejściem użytkownika do innej strony:
// 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() }
Przypisywanie kluczy do treści
Treści są modelowane w Nawigacji 3 za pomocą elementu NavEntry
, który jest klasą zawierającą funkcję składającą się z elementów. Reprezentuje miejsce docelowe – pojedynczy element treści, do którego użytkownik może przejść i z niego 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 mapowanie kluczy String
na wartości Any
, które zapewnia wszechstronne przechowywanie danych.
Aby przekształcić key
w NavEntry
, utwórz dostawcę danych wejściowych. To funkcja, która przyjmuje key
i zwraca NavEntry
dla tego key
. Jest on zwykle definiowany jako parametr lambda podczas tworzenia funkcji NavDisplay
.
Dostęp do dostawcy wpisów można uzyskać na 2 sposoby: bezpośrednio tworząc funkcję lambda lub za pomocą języka opisu entryProvider
.
Bezpośrednie tworzenie funkcji dostawcy danych wejściowych
Funkcję dostawcy danych wejściowych zwykle 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ą łączenia treści.entry
przyjmuje parametrmetadata
, aby ustawićNavEntry.metadata
Wyświetlanie stosu poprzednich elementów
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 usługa NavDisplay
monitoruje stos i odpowiednio aktualizuje interfejs. Utwórz go z tymi parametrami:
- Powrót do stosu – powinien mieć typ
SnapshotStateList<T>
, gdzieT
to typ kluczy z powrotu do stosu. 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 funkcję lambda w parametrze
onBack
. 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
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 z poprzednich elementów) obserwuje stos z poprzednich elementów. W domyślnej konfiguracji wyświetla ona najwyższy element wstecznej ścieżki 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 przekazuje powiązanyNavEntry
, który zawiera zarówno klucz, jak i treści.Treści są wyświetlane.
NavDisplay
otrzymujeNavEntry
i wyświetla zawartość.