Komponent Nawigacja używa grafu nawigacji do zarządzania nawigacją w aplikacji. Graf nawigacji to struktura danych zawierająca wszystkie miejsca docelowe w aplikacji oraz połączenia między nimi.
Typy miejsc docelowych
Istnieją 3 ogólne typy miejsc docelowych: hostowane, dialogowe i z aktywizacją. W tabeli poniżej przedstawiono te 3 typy miejsc docelowych i ich przeznaczenie.
Typ |
Opis |
Przykłady zastosowań |
|---|---|---|
Hostowane |
Wypełnia cały element nawigacji. Oznacza to, że rozmiar hostowanego miejsca docelowego jest taki sam jak rozmiar hosta nawigacji, a poprzednie miejsca docelowe są niewidoczne. |
Ekrany główne i szczegółowe. |
Dialog |
Zawiera komponenty UI nakładki. To UI nie jest powiązane z lokalizacją hosta nawigacji ani jego rozmiarem. Poprzednie miejsca docelowe są widoczne pod bieżącym miejscem docelowym. |
alerty, wybory, formularze. |
Aktywność |
Reprezentują unikalne ekrany lub funkcje w aplikacji. |
służyć jako punkt wyjścia do grafu nawigacji, który uruchamia nową aktywność Androida zarządzaną oddzielnie od komponentu nawigacji; W ramach nowoczesnego procesu tworzenia aplikacji na Androida aplikacja składa się z jednego działania. Dlatego miejsca docelowe aktywności najlepiej sprawdzają się podczas interakcji z aktywnościami innych firm lub w ramach procesu migracji. |
Ten dokument zawiera przykłady hostowanych miejsc docelowych, które są najczęstszymi i podstawowymi miejscami docelowymi. Informacje o innych usługach docelowych znajdziesz w tych przewodnikach:
Platformy
Chociaż w każdym przypadku stosuje się ten sam ogólny proces, sposób tworzenia hosta nawigacji i grafu zależy od używanej platformy interfejsu.
- Komponowanie: użyj modułu
NavHost. Dodaj do niegoNavGraphza pomocą Kotlin DSL. Możesz utworzyć wykres na 2 sposoby:- W ramach NavHost: zbuduj graf nawigacji bezpośrednio w ramach dodawania
NavHost. - Automatycznie: użyj metody
NavController.createGraph(), aby utworzyć obiektNavGraphi przekazać go bezpośrednio do obiektuNavHost.
- W ramach NavHost: zbuduj graf nawigacji bezpośrednio w ramach dodawania
- Fragmenty: jeśli fragmenty są używane z ramką interfejsu użytkownika widoków, jako hosta użyj widoku
NavHostFragment. Graf w usłudze Google Analytics można utworzyć na kilka sposobów:- Programowo: użyj Kotlin DSL, aby utworzyć
NavGraphi bezpośrednio zastosować go doNavHostFragment.- Funkcja
createGraph()używana w Kotlin DSL w przypadku fragmentów i Compose jest taka sama.
- Funkcja
- XML: zapisz hosta nawigacji i wykres bezpośrednio w formacie XML.
- Edytor Android Studio: użyj edytora GUI w Android Studio, aby utworzyć i dostosować wykres jako plik zasobu XML.
- Programowo: użyj Kotlin DSL, aby utworzyć
Compose
W komponencie Compose użyj obiektu lub klasy serializowanej, aby zdefiniować trasę. Trasa opisuje, jak dotrzeć do miejsca docelowego, i zawiera wszystkie informacje wymagane przez to miejsce.
Użyj adnotacji @Serializable, aby automatycznie utworzyć niezbędne metody serializacji i deserializacji dla typów tras. Ta adnotacja jest dostarczana przez wtyczkę Kotlin Serialization. Aby dodać tę wtyczkę, wykonaj te instrukcje.
Po zdefiniowaniu tras użyj komponentu NavHost, aby utworzyć graf nawigacji. Rozważ ten przykład:
@Serializable
object Profile
@Serializable
object FriendsList
val navController = rememberNavController()
NavHost(navController = navController, startDestination = Profile) {
composable<Profile> { ProfileScreen( /* ... */ ) }
composable<FriendsList> { FriendsListScreen( /* ... */ ) }
// Add more destinations similarly.
}
- Obiekt serializowany reprezentuje obie ścieżki:
ProfileiFriendsList. - Wywołanie komponentu
NavHostprzekazujeNavControlleri trasę do miejsca docelowego. - Funkcja lambda przekazana do
NavHostwywołuje w końcu funkcjęNavController.createGraph()i zwraca wartośćNavGraph. - Każda ścieżka jest podawana jako argument typu do
NavGraphBuilder.composable<T>(), który dodaje miejsce docelowe do otrzymanegoNavGraph. - Funkcja lambda przekazana do
composableto to, coNavHostwyświetla dla tego miejsca docelowego.
Lambda
Aby lepiej zrozumieć funkcję lambda, która tworzy zmienną NavGraph, pamiętaj, że aby utworzyć ten sam wykres co w poprzednim fragmencie kodu, możesz utworzyć zmienną NavGraph osobno za pomocą funkcji NavController.createGraph() i przekazać ją bezpośrednio do funkcji NavHost:
val navGraph by remember(navController) {
navController.createGraph(startDestination = Profile)) {
composable<Profile> { ProfileScreen( /* ... */ ) }
composable<FriendsList> { FriendsListScreen( /* ... */ ) }
}
}
NavHost(navController, navGraph)
Przekazywanie argumentów
Jeśli chcesz przekazać dane do miejsca docelowego, zdefiniuj trasę za pomocą klasy z parametrami. Na przykład trasa Profile to klasa danych z parametrem name.
@Serializable
data class Profile(val name: String)
Za każdym razem, gdy chcesz przekazać argumenty do tego miejsca docelowego, tworzysz instancję klasy trasy, przekazując argumenty do konstruktora klasy.
W przypadku argumentów opcjonalnych twórz pola z możliwością wartości null i wartością domyślną.
@Serializable
data class Profile(val nickname: String? = null)
Pobieranie instancji trasy
Możesz uzyskać instancję trasy za pomocą NavBackStackEntry.toRoute() lub SavedStateHandle.toRoute(). Gdy tworzysz miejsce docelowe za pomocą parametru composable(), parametr NavBackStackEntry jest dostępny jako parametr.
@Serializable
data class Profile(val name: String)
val navController = rememberNavController()
NavHost(navController = navController, startDestination = Profile(name="John Smith")) {
composable<Profile> { backStackEntry ->
val profile: Profile = backStackEntry.toRoute()
ProfileScreen(name = profile.name) }
}
Zwróć uwagę na te informacje w tym fragmencie kodu:
- Trasa
Profileokreśla punkt początkowy w grafu nawigacji, a argument"John Smith"w funkcjinameto"John Smith". - Miejsce docelowe to blok
composable<Profile>{}. - Składnik
ProfileScreenprzyjmuje wartośćprofile.namejako argumentname. - W związku z tym wartość
"John Smith"jest przekazywana doProfileScreen.
Minimalny przykład
Pełny przykład działania funkcji NavController i NavHost:
@Serializable
data class Profile(val name: String)
@Serializable
object FriendsList
// Define the ProfileScreen composable.
@Composable
fun ProfileScreen(
profile: Profile
onNavigateToFriendsList: () -> Unit,
) {
Text("Profile for ${profile.name}")
Button(onClick = { onNavigateToFriendsList() }) {
Text("Go to Friends List")
}
}
// Define the FriendsListScreen composable.
@Composable
fun FriendsListScreen(onNavigateToProfile: () -> Unit) {
Text("Friends List")
Button(onClick = { onNavigateToProfile() }) {
Text("Go to Profile")
}
}
// Define the MyApp composable, including the `NavController` and `NavHost`.
@Composable
fun MyApp() {
val navController = rememberNavController()
NavHost(navController, startDestination = Profile(name = "John Smith")) {
composable<Profile> { backStackEntry ->
val profile: Profile = backStackEntry.toRoute()
ProfileScreen(
profile = profile,
onNavigateToFriendsList = {
navController.navigate(route = FriendsList)
}
)
}
composable<FriendsList> {
FriendsListScreen(
onNavigateToProfile = {
navController.navigate(
route = Profile(name = "Aisha Devi")
)
}
)
}
}
}
Jak widać w tym fragmencie kodu, zamiast przekazywać parametr NavController do komponentów, należy ujawnić zdarzenie dla parametru NavHost. Oznacza to, że twoje komponenty powinny mieć parametr typu () -> Unit, do którego NavHost przekazuje funkcję lambda, która wywołuje funkcję NavController.navigate().
Fragmenty
Jak opisano w poprzednich sekcjach, podczas korzystania z fragmentów możesz utworzyć graficzną mapę nawigacji za pomocą Kotlin DSL, XML lub edytora Android Studio.
W następnych sekcjach omawiamy te różne podejścia.
Automatycznie
Kotlin DSL zapewnia programowy sposób tworzenia grafu nawigacyjnego za pomocą fragmentów. W wielu aspektach jest to rozwiązanie bardziej przejrzyste i nowocześniejsze niż używanie pliku zasobów XML.
Rozważ przykład poniżej, który wdraża wykres nawigacji na 2 ekranach.
Najpierw musisz utworzyć element NavHostFragment, który nie może zawierać element app:navGraph:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
Następnie przekaż id z NavHostFragment do NavController.findNavController. W ten sposób kontroler nawigacji zostaje powiązany z elementem NavHostFragment.
Następnie wywołanie funkcji NavController.createGraph() łączy wykres z funkcją NavController, a w konsekwencji także z funkcją NavHostFragment:
@Serializable
data class Profile(val name: String)
@Serializable
object FriendsList
// Retrieve the NavController.
val navController = findNavController(R.id.nav_host_fragment)
// Add the graph to the NavController with `createGraph()`.
navController.graph = navController.createGraph(
startDestination = Profile(name = "John Smith")
) {
// Associate each destination with one of the route constants.
fragment<ProfileFragment, Profile> {
label = "Profile"
}
fragment<FriendsListFragment, FriendsList>() {
label = "Friends List"
}
// Add other fragment destinations similarly.
}
Używanie DSL w ten sposób jest bardzo podobne do procesu opisanego w poprzedniej sekcji dotyczącej tworzenia. Na przykład w obu przypadkach funkcja NavController.createGraph() generuje wartość NavGraph. Podobnie jak NavGraphBuilder.composable() dodaje do grafu miejsca docelowe, które można łączyć, tak NavGraphBuilder.fragment() dodaje fragment miejsca docelowego.
Więcej informacji o korzystaniu z języka DSL w Kotlinie znajdziesz w artykule Tworzenie grafu za pomocą DSL w klasie NavGraphBuilder.
XML
Możesz samodzielnie napisać kod XML. Poniższy przykład jest lustrzanym odpowiednikiem przykładu z 2 ekranami z poprzedniej sekcji.
Najpierw utwórz NavHostFragment. Jest to host nawigacji, który zawiera rzeczywisty graf nawigacji.
Minimalna implementacja NavHostFragment:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:navGraph="@navigation/nav_graph" />
</FrameLayout>
Element NavHostFragment zawiera atrybut app:navGraph. Użyj tego atrybutu, aby połączyć graf nawigacji z hostem nawigacji. Poniżej znajdziesz przykład implementacji wykresu:
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/nav_graph"
app:startDestination="@id/profile">
<fragment
android:id="@+id/profile"
android:name="com.example.ProfileFragment"
android:label="Profile">
<!-- Action to navigate from Profile to Friends List. -->
<action
android:id="@+id/action_profile_to_friendslist"
app:destination="@id/friendslist" />
</fragment>
<fragment
android:id="@+id/friendslist"
android:name="com.example.FriendsListFragment"
android:label="Friends List" />
<!-- Add other fragment destinations similarly. -->
</navigation>
Za pomocą działań określasz połączenia między różnymi miejscami docelowymi. W tym przykładzie fragment profile zawiera działanie, które przekierowuje do fragmentu friendslist. Więcej informacji znajdziesz w artykule Używanie działań i fragmentów nawigacji.
Edytor
Grafikiem nawigacji aplikacji możesz zarządzać za pomocą Edytora nawigacji w Android Studio. Jest to interfejs graficzny, którego możesz używać do tworzenia i edytowania pliku XML NavigationFragment, jak pokazano w poprzedniej sekcji.
Więcej informacji znajdziesz w Edytorze nawigacji.
Wykresy zagnieżdżone
Możesz też używać wykresów zagnieżdżonych. Polega to na użyciu grafu jako celu nawigacji. Więcej informacji znajdziesz w artykule Wyrażenia z wykresami zagnieżdżonymi.
Więcej informacji
Więcej informacji o podstawowych pojęciach związanych z nawigacją znajdziesz w tych przewodnikach:
- Omówienie: zapoznaj się z ogólnym omówieniem komponentu Nawigacja.
- Miejsca docelowe aktywności: przykłady implementacji miejsc docelowych, które kierują użytkownika do aktywności.
- Strony docelowe dialogu: przykłady tworzenia stron docelowych, które przekierowują użytkownika do dialogu.
- Nawigacja do miejsca docelowego: szczegółowy przewodnik, który pokazuje, jak poruszać się z jednego miejsca docelowego do drugiego.
- Grafiki zagnieżdżone: szczegółowy przewodnik po zagnieżdżaniu jednego elementu graficznego nawigacji w innym.