Komponent Nawigacja korzysta z wykresu nawigacyjnego, który służy do zarządzania nawigacją w aplikacji. Wykres nawigacyjny to struktura danych obejmująca wszystkie miejsca docelowe w aplikacji i połączenia między nimi.
Typy miejsc docelowych
Istnieją 3 ogólne typy miejsc docelowych: hostowane, okno i aktywność. W tabeli poniżej przedstawiamy te 3 typy miejsc docelowych i ich przeznaczenie.
Typ |
Opis |
Przykłady zastosowań |
---|---|---|
Hostowane |
Wypełnia cały host nawigacji. Oznacza to, że rozmiar hostowanego miejsca docelowego jest taki sam jak rozmiar hosta nawigacji, a poprzednie miejsca docelowe nie są widoczne. |
Ekran główny i ekran ze szczegółami. |
Dialog |
Prezentuje komponenty interfejsu nakładki. Ten interfejs nie jest powiązany z lokalizacją hosta nawigacji ani jego rozmiarem. Pod miejscem docelowym będą widoczne poprzednie miejsca docelowe. |
Alerty, wybory, formularze. |
Aktywność |
Reprezentuje unikalne ekrany lub funkcje aplikacji. |
Pełni funkcję punktu wyjścia do wykresu nawigacyjnego, które uruchamia nowe działanie Androida, którym zarządza się niezależnie od komponentu Nawigacja. We współczesnym programowaniu na Androida aplikacja składa się z jednej aktywności. Dlatego miejsca docelowe aktywności najlepiej sprawdzają się podczas interakcji z aktywnościami osób trzecich lub podczas procesu migracji. |
Ten dokument zawiera przykłady hostowanych miejsc docelowych – najczęściej używanych i podstawowych miejsc docelowych. Informacje o innych miejscach docelowych znajdziesz w tych przewodnikach:
Platformy
Chociaż w każdym przypadku ten sam ogólny przepływ pracy ma zastosowanie, to sposób dokładnego tworzenia hosta i wykresu nawigacji zależy od używanej przez Ciebie platformy UI.
- Tworzenie: użyj funkcji kompozycyjnej
NavHost
. Dodaj do niegoNavGraph
, korzystając z DSL Kotlin. Wykres możesz utworzyć na 2 sposoby:- W ramach NavHost: podczas dodawania
NavHost
utwórz wykres nawigacyjny bezpośrednio. - Automatycznie: użyj metody
NavController.createGraph()
, aby utworzyć dokumentNavGraph
i przekazać go bezpośrednio doNavHost
.
- W ramach NavHost: podczas dodawania
- Fragmenty: jeśli używasz fragmentów z platformą Widoki UI, jako hosta użyj
NavHostFragment
. Wykres nawigacyjny można utworzyć na kilka sposobów:- Automatyzacja: użyj DSL Kotlin, aby utworzyć
NavGraph
i bezpośrednio zastosować go doNavHostFragment
.- Funkcja
createGraph()
używana w przypadku DSL Kotlin zarówno w przypadku fragmentów, jak i tworzenia jest taka sama.
- Funkcja
- XML:zapisz host i wykres nawigacji bezpośrednio w formacie XML.
- Edytor Android Studio: użyj edytora graficznego w Android Studio, aby utworzyć i dostosować wykres jako plik zasobów XML.
- Automatyzacja: użyj DSL Kotlin, aby utworzyć
Utwórz
W narzędziu Compose użyj obiektu lub klasy możliwej do serializacji, aby zdefiniować trasę. Trasa zawiera informacje o tym, jak dotrzeć do celu, oraz wszystkie niezbędne informacje. Po zdefiniowaniu tras użyj funkcji NavHost
kompozycyjnej, aby utworzyć wykres nawigacyjny. Przeanalizuj 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 możliwe do serializowania reprezentuje każdą z 2 tras:
Profile
iFriendsList
. - Wywołanie funkcji kompozycyjnej
NavHost
przekazujeNavController
i trasę miejsca docelowego początkowego. - Funkcja lambda przekazana do interfejsu
NavHost
ostatecznie wywołuje metodęNavController.createGraph()
i zwracaNavGraph
. - Każda trasa jest podawana jako argument typu
NavGraphBuilder.composable<T>()
, który dodaje miejsce docelowe do wynikowego argumentuNavGraph
. - Funkcja lambda przekazana do
composable
jest tym, co wyświetlaNavHost
w przypadku tego miejsca docelowego.
Czym jest lambda
Aby lepiej zrozumieć funkcję lambda, która tworzy NavGraph
, rozważ utworzenie tego samego wykresu co w poprzednim fragmencie kodu. Możesz utworzyć parametr NavGraph
oddzielnie za pomocą funkcji NavController.createGraph()
i przekazać go bezpośrednio do interfejsu NavHost
:
val navGraph by remember(navController) {
navController.createGraph(startDestination = Profile)) {
composable<Profile> { ProfileScreen( /* ... */ ) }
composable<FriendsList> { FriendsListScreen( /* ... */ ) }
}
}
NavHost(navController, navGraph)
Argumenty przekazywania
Jeśli musisz przekazywać 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 musisz przekazać argumenty do tego miejsca docelowego, tworzysz instancję klasy trasy, która przekazuje argumenty do konstruktora klas.
Uzyskiwanie instancji trasy
Instancję trasy możesz uzyskać za pomocą NavBackStackEntry.toRoute()
lub SavedStateHandle.toRoute()
. Gdy tworzysz miejsce docelowe za pomocą właściwości composable()
, jako parametr dostępny jest NavBackStackEntry
.
@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 kwestie:
- Trasa
Profile
określa początkowe miejsce docelowe na wykresie nawigacyjnym przy użyciu elementu"John Smith"
jako argumentuname
. - Miejsce docelowe to blok
composable<Profile>{}
. - Funkcja kompozycyjna
ProfileScreen
przyjmuje wartośćprofile.name
dla własnego argumentuname
. - Dlatego wartość
"John Smith"
jest przekazywana doProfileScreen
.
Minimalny przykład
Pełen przykład współdziałania elementów 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( onNavigateToFriendsList() }) {
Text("Go to Friends List")
}
}
// Define the FriendsListScreen composable.
@Composable
fun FriendsListScreen(onNavigateToProfile: () -> Unit) {
Text("Friends List")
Button( 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,
navController.navigate(route = FriendsList)
}
)
}
composable<FriendsList> {
FriendsListScreen(
navController.navigate(
route = Profile(name = "Aisha Devi")
)
}
)
}
}
}
Jak widać we fragmencie kodu, zamiast przekazywać zdarzenie NavController
do funkcji kompozycyjnej, ujawnij zdarzenie w interfejsie NavHost
. Oznacza to, że obiekty kompozycyjne powinny mieć parametr typu () -> Unit
, dla którego obiekt NavHost
przekazuje parametr lambda wywołujący NavController.navigate()
.
Fragmenty
Jak wspomnieliśmy w poprzednich sekcjach, używając fragmentów, można automatycznie utworzyć wykres nawigacyjny automatycznie za pomocą edytora Kotlin DSL, XML lub edytora Android Studio.
W sekcjach poniżej szczegółowo opisujemy poszczególne podejścia.
Automatycznie
DSL Kotlin umożliwia zautomatyzowane tworzenie wykresu nawigacyjnego z fragmentami. Pod wieloma względami jest to bardziej eleganckie i nowoczesne niż korzystanie z pliku zasobów XML.
Przyjrzyjmy się przykładowi, w którym zaimplementowano dwuekranowy wykres nawigacyjny.
Najpierw musisz utworzyć obiekt NavHostFragment
, który nie może zawierać elementu 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
(NavHostFragment
) maszynie wirtualnej NavController.findNavController
. Powiąże to kontroler nawigacji z elementem NavHostFragment
.
Następnie wywołanie NavController.createGraph()
łączy wykres z tabelą NavController
, a tym samym z tabelą 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 procedury opisanej w poprzedniej sekcji dotyczącej tworzenia. Na przykład zarówno w tym miejscu, jak i w tym miejscu funkcja NavController.createGraph()
generuje NavGraph
. I podobnie, NavGraphBuilder.composable()
dodaje do wykresu miejsca docelowe kompozycyjne, tutaj NavGraphBuilder.fragment()
dodaje miejsce docelowe fragmentu.
Więcej informacji o korzystaniu z DSL Kotlin znajdziesz w artykule Tworzenie wykresu przy użyciu DSL NavGraphBuilder.
XML
Kod XML możesz zapisać bezpośrednio. Poniżej znajduje się przykład, który jest odpowiednikiem dwuekranowego przykładu z poprzedniej sekcji.
Najpierw utwórz NavHostFragment
. Służy jako host nawigacji, który zawiera rzeczywisty wykres nawigacyjny.
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>
NavHostFragment
zawiera atrybut app:navGraph
. Użyj tego atrybutu, aby połączyć wykres nawigacyjny z hostem nawigacji. Oto 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>
Do definiowania połączeń między różnymi miejscami docelowymi służą działania. W tym przykładzie fragment profile
zawiera działanie powodujące przejście do adresu friendslist
. Więcej informacji znajdziesz w artykule Używanie działań i fragmentów nawigacji.
Edytujący
Wykresem nawigacyjnym aplikacji możesz zarządzać za pomocą edytora nawigacji w Android Studio. Jest to w zasadzie GUI, którego można użyć do tworzenia i edytowania kodu XML NavigationFragment
, tak jak to pokazano w poprzedniej sekcji.
Więcej informacji znajdziesz w artykule Edytor nawigacji.
Zagnieżdżone wykresy
Możesz też używać zagnieżdżonych wykresów. Wiąże się to z wykorzystaniem wykresu jako miejsca docelowego nawigacji. Więcej informacji znajdziesz w artykule Wykresy zagnieżdżone.
Dalsza lektura
Więcej podstawowych pojęć związanych z nawigacją znajdziesz w tych przewodnikach:
- Omówienie: przeczytaj ogólne omówienie komponentu Nawigacja.
- Miejsca docelowe działań: przykłady implementacji miejsc docelowych, które kierują użytkownika do działań.
- Miejsca docelowe okien: przykłady tworzenia miejsc docelowych, które kierują użytkownika do okna.
- Nawigacja do miejsca docelowego: szczegółowy przewodnik, z którego dowiesz się, jak poruszać się między miejscami docelowymi.
- Wykresy zagnieżdżone: szczegółowy przewodnik pokazujący, jak zagnieżdżać jeden wykres nawigacyjny w innym.