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 niegoNavGraph
za 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ć obiektNavGraph
i 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ć
NavGraph
i 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:
Profile
iFriendsList
. - Wywołanie komponentu
NavHost
przekazujeNavController
i trasę do miejsca docelowego. - Funkcja lambda przekazana do
NavHost
wywoł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
composable
to to, coNavHost
wyś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
Profile
określa punkt początkowy w grafu nawigacji, a argument"John Smith"
w funkcjiname
to"John Smith"
. - Miejsce docelowe to blok
composable<Profile>{}
. - Składnik
ProfileScreen
przyjmuje wartośćprofile.name
jako 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.