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 einNavGraph
hinzu. 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 eineNavGraph
zu erstellen und direkt an dieNavHost
zu ü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
NavHostFragment
als Host. Es gibt mehrere Möglichkeiten, einen Navigationsgraphen zu erstellen:- Programmatisch:Mit der Kotlin DSL eine
NavGraph
erstellen und direkt auf dieNavHostFragment
anwenden.- 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,
Profile
undFriendsList
. - Der Aufruf des
NavHost
-Kompositionselements übergibt einenNavController
und eine Route für den Startpunkt. - Das an
NavHost
übergebene Lambda ruft letztendlichNavController.createGraph()
auf und gibt einenNavGraph
zurück. - Jede Route wird als Typargument an
NavGraphBuilder.composable<T>()
übergeben, wodurch das Ziel der resultierendenNavGraph
hinzugefügt wird. - Das an
composable
übergebene Lambda wird inNavHost
fü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
Profile
gibt den Startpunkt im Navigationsgraphen an, wobei"John Smith"
das Argument fürname
ist. - Das Ziel selbst ist der
composable<Profile>{}
-Block. - Das
ProfileScreen
-Komposit nimmt den Wert vonprofile.name
fü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.