Komponent Nawigacja używa wykresu nawigacyjnego do zarządzania poruszaniem się po aplikacji. Wykres nawigacyjny to struktura danych, która obejmuje wszystkie miejsca docelowe w aplikacji oraz połączenia między nimi.
Typy miejsc docelowych
Istnieją 3 ogólne typy miejsc docelowych: hostowane, okna dialogowe i aktywność. W poniższej tabeli opisujemy 3 typy miejsc docelowych i ich zastosowania.
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 szczegółów. |
Dialog |
Widoczne są komponenty interfejsu nakładki. Nie jest on powiązany z lokalizacją hosta nawigacji ani jego rozmiarem. Poprzednie miejsca docelowe są widoczne poniżej miejsca docelowego. |
Alerty, wybory, formularze. |
Aktywność |
Reprezentuje unikalne ekrany lub funkcje aplikacji. |
Pełni funkcję punktu wyjścia z wykresu nawigacyjnego, który rozpoczyna nową aktywność na Androidzie zarządzanym niezależnie od komponentu Nawigacja. We współczesnych programach na Androida aplikacja składa się z jednego działania. Dlatego miejsc docelowych aktywności najlepiej jest używać podczas interakcji z działaniami zewnętrznymi lub w ramach procesu migracji. |
Ten dokument zawiera przykłady hostowanych miejsc docelowych, które są najpopularniejsze i najbardziej podstawowe. W tych przewodnikach znajdziesz informacje o innych usługach docelowych:
Platformy
W każdym przypadku obowiązuje ten sam ogólny przepływ pracy, ale dokładny sposób tworzenia hosta nawigacji i wykresu zależy od używanej platformy interfejsu.
- Utwórz: użyj funkcji kompozycyjnej
NavHost
. Dodaj do niegoNavGraph
za pomocą DLSL Kotlin. Wykres można utworzyć na 2 sposoby:- W ramach obiektu NavHost: utwórz wykres nawigacyjny bezpośrednio w ramach dodawania obiektu
NavHost
. - Automatycznie: użyj metody
NavController.createGraph()
, aby utworzyćNavGraph
i przekazać go bezpośrednio doNavHost
.
- W ramach obiektu NavHost: utwórz wykres nawigacyjny bezpośrednio w ramach dodawania obiektu
- Fragmenty: jeśli używasz fragmentów w strukturze interfejsu widoków, hostem jest
NavHostFragment
. Wykres nawigacyjny można utworzyć na kilka sposobów:- Programowo: użyj DSL Kotlin, aby utworzyć
NavGraph
i zastosować go bezpośrednio doNavHostFragment
.- Funkcja
createGraph()
używana z DSL Kotlin zarówno w przypadku fragmentów, jak i tworzenia wiadomości jest taka sama.
- Funkcja
- XML: wpisz host nawigacji i wykres bezpośrednio w pliku XML.
- Edytor Android Studio: użyj edytora GUI w Android Studio, aby utworzyć i dostosować wykres jako plik zasobów XML.
- Programowo: użyj DSL Kotlin, aby utworzyć
Utwórz
W narzędziu Compose zdefiniuj trasę za pomocą zserializowanego obiektu lub klasy. Trasa określa, jak dotrzeć do celu, i zawiera wszystkie wymagane informacje. Po zdefiniowaniu tras użyj funkcji NavHost
, aby utworzyć wykres nawigacyjny. Przyjrzyjmy się temu przykładowi:
@Serializable
object Profile
@Serializable
object FriendsList
val navController = rememberNavController()
NavHost(navController = navController, startDestination = Profile) {
composable<Profile> { ProfileScreen( /* ... */ ) }
composable<FriendsList> { FriendsListScreen( /* ... */ ) }
// Add more destinations similarly.
}
- Zserializowany obiekt reprezentuje każdą z 2 tras –
Profile
iFriendsList
. - Wywołanie funkcji kompozycyjnej
NavHost
przekazujeNavController
i trasę do miejsca docelowego początkowego. - Funkcja lambda przekazana do funkcji
NavHost
ostatecznie wywołujeNavController.createGraph()
i zwracaNavGraph
. - Każda trasa jest dostarczana jako argument typu w funkcji
NavGraphBuilder.composable<T>()
, który dodaje miejsce docelowe do wynikowegoNavGraph
. - Wartość lambda przekazana do
composable
to wynik, któryNavHost
wyświetla w przypadku danego miejsca docelowego.
Omówienie funkcji lambda
Aby lepiej zrozumieć, do czego służy funkcja lambda, która tworzy obiekt NavGraph
, pamiętaj, że aby utworzyć taki sam wykres jak w poprzednim fragmencie, możesz utworzyć tabelę NavGraph
oddzielnie 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 musisz przekazać dane do miejsca docelowego, zdefiniuj trasę za pomocą klasy z parametrami. Na przykład trasa Profile
jest klasą 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, przekazując argumenty do konstruktora klas.
Uzyskiwanie instancji trasy
Instancję trasy można uzyskać za pomocą metody NavBackStackEntry.toRoute()
lub SavedStateHandle.toRoute()
. Gdy tworzysz miejsce docelowe za pomocą funkcji composable()
, parametr NavBackStackEntry
jest dostępny.
@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) }
}
Uwaga:
- Trasa
Profile
określa miejsce docelowe początkowe na wykresie nawigacyjnym, przy czym argument"John Smith"
to argumentname
. - Samo miejsce docelowe to blok
composable<Profile>{}
. - Funkcja kompozycyjna
ProfileScreen
przyjmuje wartośćprofile.name
jako własny argumentname
. - W związku z tym wartość
"John Smith"
przekazuje się doProfileScreen
.
Przykład z minimalną ilością danych
Kompletny 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(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 pokazuje fragment kodu, zamiast przekazywać NavController
do funkcji kompozycyjnych, ujawniaj zdarzenie funkcji NavHost
. Oznacza to, że obiekty kompozycyjne powinny mieć parametr typu () -> Unit
, dla którego funkcja NavHost
przekazuje funkcję lambda wywołującą NavController.navigate()
.
Fragmenty
Jak wspomnieliśmy w poprzednich sekcjach, gdy używasz fragmentów, możesz automatycznie utworzyć wykres nawigacyjny za pomocą narzędzia DSL, XML lub edytora Android Studio.
Szczegółowe informacje na ten temat znajdziesz w sekcjach poniżej.
Automatyzacja
Za pomocą technologii DSL Kotlin można w sposób zautomatyzowany tworzyć graf nawigacji z fragmentami. Jest to pod wieloma względami bardziej uporządkowane i nowoczesne niż użycie pliku zasobów XML.
Przyjrzyjmy się przykładowi, w którym zastosowano wykres nawigacji na 2 ekrany.
Najpierw musisz utworzyć 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
z NavHostFragment
do NavController.findNavController
. Powiąże to element NavController z elementem NavHostFragment
.
Następnie wywołanie NavController.createGraph()
łączy wykres z tabelą NavController
, a w konsekwencji także 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.
}
Ten sposób korzystania z DSL jest bardzo podobny do przepływu pracy opisanego w poprzedniej sekcji Tworzenie. Na przykład zarówno tam, jak i tutaj funkcja NavController.createGraph()
generuje NavGraph
. Podobnie, mimo że NavGraphBuilder.composable()
dodaje do wykresu miejsca docelowe kompozycyjne, tutaj NavGraphBuilder.fragment()
dodaje miejsce docelowe dla fragmentu.
Więcej informacji o tym, jak korzystać z DSL Kotlin, znajdziesz w artykule Tworzenie wykresu za pomocą narzędzia NavGraphBuilder DSL.
XML
Kod XML możesz wpisać bezpośrednio samodzielnie. Poniższy przykład odzwierciedla i odnosi się do przykładu z 2 ekranami z poprzedniej sekcji.
Najpierw utwórz NavHostFragment
. Służy on jako host nawigacji, który zawiera rzeczywisty wykres nawigacji.
Minimalna implementacja elementu 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ładowa implementacja 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>
Działają one do definiowania połączeń między różnymi miejscami docelowymi. W tym przykładzie fragment profile
zawiera działanie, które prowadzi do strony friendslist
. Więcej informacji znajdziesz w artykule Korzystanie z działań i fragmentów nawigacji.
Edytor
Możesz zarządzać wykresem nawigacji aplikacji, korzystając z edytora nawigacji w Android Studio. Jest to zasadniczo GUI, którego możesz użyć do utworzenia i edytowania pliku XML NavigationFragment
, jak pokazano w poprzedniej sekcji.
Więcej informacji znajdziesz w sekcji Edytor nawigacji.
Wykresy zagnieżdżone
Możesz też używać wykresów zagnieżdżonych. 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 aktywności: przykłady implementacji miejsc docelowych, które przenoszą użytkownika do określonych działań.
- Miejsca docelowe okien: przykłady tworzenia miejsc docelowych kierujących użytkownika do okna.
- Nawigowanie do celu: szczegółowy przewodnik z informacjami o tym, jak dotrzeć z jednego miejsca docelowego do drugiego.
- Wykresy zagnieżdżone: szczegółowy przewodnik na temat zagnieżdżania wykresów nawigacyjnych w obrębie innego.