Die Navigationskomponente verwendet einen Navigationsgraphen, um die Navigation Ihrer App zu verwalten. Der Navigationsgraph ist eine Datenstruktur, die alle Ziele in Ihrer App und die Verbindungen zwischen ihnen enthält.
Zieltypen
Es gibt drei allgemeine Zieltypen: gehostete, Dialog- und Aktivitätsziele. In der folgenden Tabelle werden diese drei Zieltypen und ihre Zwecke beschrieben.
Eingeben |
Beschreibung |
Anwendungsfälle |
|---|---|---|
Gehostet |
Füllt den gesamten Navigationshost aus. Das heißt, die Größe eines gehosteten Ziels entspricht der Größe des Navigationshosts und vorherige Ziele sind nicht sichtbar. |
Haupt- und Detailbildschirme |
Dialogfeld |
Zeigt UI-Overlay-Komponenten an. Diese Benutzeroberfläche ist nicht an den Standort oder die Größe des Navigationshosts gebunden. Bisherige Ziele werden unter dem Ziel angezeigt. |
Benachrichtigungen, Auswahlen, Formulare. |
Aktivität |
Stellt eindeutige Bildschirme oder Funktionen in der App dar. |
Als Ausstiegspunkt für den Navigationsgraphen dienen, über den eine neue Android-Aktivität gestartet wird, die separat von der Navigationskomponente verwaltet wird. Bei der modernen Android-Entwicklung besteht eine App aus einer einzelnen Aktivität. Aktivitätsziele eignen sich daher am besten für Interaktionen mit Aktivitäten von Drittanbietern oder als Teil des Migrationsprozesses. |
Dieses Dokument enthält Beispiele für gehostete Ziele, die am häufigsten und grundlegendsten sind. Informationen zu den anderen Zielen finden Sie in den folgenden Leitfäden:
Frameworks
Obwohl in jedem Fall derselbe allgemeine Workflow gilt, hängt die genaue Erstellung eines Navigationshosts und -diagramms vom verwendeten UI-Framework ab.
- Compose (Komponieren): Verwenden Sie das
NavHost-Element. Fügen Sie mit der Kotlin-DSL einNavGraphhinzu. Es gibt zwei Möglichkeiten, den Graphen zu erstellen:- Im NavHost:Erstellen Sie den Navigationsgraphen direkt beim Hinzufügen der
NavHost. - Programmatisch:Verwenden Sie die Methode
NavController.createGraph(), um eineNavGraphzu erstellen und direkt an dieNavHostzu übergeben.
- Im NavHost:Erstellen Sie den Navigationsgraphen direkt beim Hinzufügen der
- Fragmente:Wenn Sie Fragmente mit dem UI-Framework von Google-Diensten verwenden, verwenden Sie
NavHostFragmentals Host. Es gibt mehrere Möglichkeiten, einen Navigationsgraphen zu erstellen:- Programmatisch:Mit der Kotlin DSL eine
NavGrapherstellen und direkt auf dieNavHostFragmentanwenden.- Die
createGraph()-Funktion, die in der Kotlin-DSL sowohl für Fragmente als auch für Compose verwendet wird, ist dieselbe.
- Die
- XML:Navigations-Host und -Grafik direkt in XML schreiben
- Android Studio-Editor:Mit dem GUI-Editor in Android Studio können Sie Ihre Grafik als XML-Ressourcendatei erstellen und anpassen.
- Programmatisch:Mit der Kotlin DSL eine
Schreiben
Verwenden Sie in Compose ein serialisierbares Objekt oder eine serialisierbare Klasse, um eine Route zu definieren. Eine Route beschreibt, wie Sie zu einem Ziel gelangen, und enthält alle Informationen, die für das Ziel erforderlich sind.
Verwenden Sie die Anmerkung @Serializable, um automatisch die erforderlichen Serializations- und Deserializationsmethoden für Ihre Routentypen zu erstellen. Diese Anmerkung wird vom Kotlin-Serialisierungs-Plug-in bereitgestellt. Folgen Sie dieser Anleitung, um das Plug-in hinzuzufügen.
Nachdem Sie Ihre Routen definiert haben, erstellen Sie mit dem NavHost-Element den Navigationsgraphen. Betrachten Sie das folgende Beispiel:
@Serializable
object Profile
@Serializable
object FriendsList
val navController = rememberNavController()
NavHost(navController = navController, startDestination = Profile) {
composable<Profile> { ProfileScreen( /* ... */ ) }
composable<FriendsList> { FriendsListScreen( /* ... */ ) }
// Add more destinations similarly.
}
- Ein serialisierbares Objekt steht für jede der beiden Routen,
ProfileundFriendsList. - Der Aufruf des
NavHost-Kompositionselements übergibt einenNavControllerund eine Route für den Startpunkt. - Das an
NavHostübergebene Lambda ruft letztendlichNavController.createGraph()auf und gibt einenNavGraphzurück. - Jede Route wird als Typargument an
NavGraphBuilder.composable<T>()übergeben, wodurch das Ziel der resultierendenNavGraphhinzugefügt wird. - Das an
composableübergebene Lambda wird inNavHostfür dieses Ziel angezeigt.
Lambda
Um das Lambda besser zu verstehen, mit dem die NavGraph erstellt wird, können Sie sich vorstellen, dass Sie denselben Graphen wie im vorherigen Snippet erstellen, indem Sie die NavGraph separat mit NavController.createGraph() erstellen und direkt an die NavHost übergeben:
val navGraph by remember(navController) {
navController.createGraph(startDestination = Profile)) {
composable<Profile> { ProfileScreen( /* ... */ ) }
composable<FriendsList> { FriendsListScreen( /* ... */ ) }
}
}
NavHost(navController, navGraph)
Karten-/Ticketargumente
Wenn Sie Daten an ein Ziel übergeben müssen, definieren Sie die Route mit einer Klasse mit Parametern. Die Route Profile ist beispielsweise eine Datenklasse mit dem Parameter name.
@Serializable
data class Profile(val name: String)
Wenn Sie diesem Ziel Argumente übergeben müssen, erstellen Sie eine Instanz Ihrer Routenklasse und übergeben die Argumente an den Klassenkonstruktor.
Erstellen Sie für optionale Argumente Felder mit Nullwerten und einem Standardwert.
@Serializable
data class Profile(val nickname: String? = null)
Routen-Instanz abrufen
Sie können die Routen-Instanz mit NavBackStackEntry.toRoute() oder SavedStateHandle.toRoute() abrufen. Wenn Sie ein Ziel mit composable() erstellen, ist NavBackStackEntry als Parameter verfügbar.
@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) }
}
Beachten Sie in diesem Snippet Folgendes:
- Die Route
Profilegibt den Startpunkt im Navigationsgraphen an, wobei"John Smith"das Argument fürnameist. - Das Ziel selbst ist der
composable<Profile>{}-Block. - Das
ProfileScreen-Komposit nimmt den Wert vonprofile.namefür sein eigenesname-Argument an. - Daher wird der Wert
"John Smith"anProfileScreenübergeben.
Minimalbeispiel
Vollständiges Beispiel für die Kombination von NavController und 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")
)
}
)
}
}
}
Wie das Snippet zeigt, übergeben Sie die NavController nicht an Ihre Composeables, sondern stellen Sie der NavHost ein Ereignis zur Verfügung. Das heißt, Ihre Composeables sollten einen Parameter vom Typ () -> Unit haben, für den NavHost ein Lambda übergibt, das NavController.navigate() aufruft.
Fragmente
Wie in den vorherigen Abschnitten beschrieben, haben Sie bei der Verwendung von Fragmenten die Möglichkeit, einen Navigationsgraphen programmatisch mit der Kotlin-DSL, XML oder dem Android Studio-Editor zu erstellen.
In den folgenden Abschnitten werden diese verschiedenen Ansätze beschrieben.
Programmatisch
Die Kotlin-DSL bietet eine programmatische Möglichkeit, einen Navigationsgraphen mit Fragmenten zu erstellen. Das ist in vielerlei Hinsicht übersichtlicher und moderner als die Verwendung einer XML-Ressourcendatei.
Betrachten Sie das folgende Beispiel, in dem ein Navigationsgraph mit zwei Bildschirmen implementiert ist.
Zuerst müssen Sie die NavHostFragment erstellen. Sie darf kein app:navGraph-Element enthalten:
<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>
Übergeben Sie als Nächstes die id der NavHostFragment an NavController.findNavController. Dadurch wird der NavController mit der NavHostFragment verknüpft.
Anschließend wird durch den Aufruf von NavController.createGraph() die Grafik mit der NavController und damit auch mit der NavHostFragment verknüpft:
@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.
}
Die Verwendung der DSL auf diese Weise ähnelt dem Workflow, der im vorherigen Abschnitt zu Compose beschrieben wurde. Sowohl dort als auch hier wird beispielsweise die NavGraph durch die Funktion NavController.createGraph() generiert. Ebenso wird mit NavGraphBuilder.composable() dem Diagramm ein zusammensetzbares Ziel hinzugefügt, während hier mit NavGraphBuilder.fragment() ein Fragmentziel hinzugefügt wird.
Weitere Informationen zur Verwendung der Kotlin-DSL finden Sie unter Graphen mit der NavGraphBuilder-DSL erstellen.
XML
Sie können die XML-Datei auch selbst schreiben. Das folgende Beispiel entspricht dem Beispiel mit zwei Bildschirmen aus dem vorherigen Abschnitt.
Erstellen Sie zuerst eine NavHostFragment. Dieser dient als Navigationshost, der das eigentliche Navigationsdiagramm enthält.
Eine minimale Implementierung eines 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 enthält das Attribut app:navGraph. Verwenden Sie dieses Attribut, um Ihren Navigationsgraphen mit dem Navigationshost zu verbinden. Im Folgenden finden Sie ein Beispiel für die Implementierung der Grafik:
<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>
Mit Aktionen definieren Sie die Verbindungen zwischen verschiedenen Zielen. In diesem Beispiel enthält das profile-Fragment eine Aktion, die zu friendslist führt. Weitere Informationen finden Sie unter Navigationsaktionen und ‑fragmente verwenden.
Editor
Sie können den Navigationsgraphen Ihrer App mit dem Navigationseditor in Android Studio verwalten. Dies ist im Wesentlichen eine Benutzeroberfläche, mit der Sie Ihre NavigationFragment-XML-Datei erstellen und bearbeiten können, wie im vorherigen Abschnitt gezeigt.
Weitere Informationen finden Sie unter Navigationseditor.
Verschachtelte Grafiken
Sie können auch verschachtelte Diagramme verwenden. Dazu wird ein Graph als Navigationsziel verwendet. Weitere Informationen finden Sie unter Verschachtelte Diagramme.
Weitere Informationen
Weitere Informationen zu den wichtigsten Navigationskonzepten finden Sie in den folgenden Leitfäden:
- Übersicht:Lesen Sie sich die allgemeine Übersicht über die Navigationskomponente durch.
- Aktivitätsziele:Beispiele für die Implementierung von Zielen, über die Nutzer zu Aktivitäten weitergeleitet werden.
- Dialogziele:Beispiele für die Erstellung von Zielen, über die Nutzer zu einem Dialog weitergeleitet werden.
- Zu einem Ziel navigieren:Eine detaillierte Anleitung zum Navigieren von einem Ziel zum anderen.
- Verschachtelte Grafiken:Eine ausführliche Anleitung zum Verschachteln eines Navigationsdiagramms in einem anderen.