Die Navigation-Komponente bietet eine einfache und allgemeine Möglichkeit, zu einem Ziel zu navigieren. Diese Schnittstelle unterstützt eine Reihe von Kontexten und UI-Frameworks. Sie können die Navigationskomponente beispielsweise mit Compose, Ansichten, Fragmenten, Aktivitäten und sogar benutzerdefinierten UI-Frameworks verwenden.
In diesem Leitfaden wird beschrieben, wie Sie mit der Navigationskomponente in verschiedenen Kontexten zu einem Ziel navigieren können.
NavController verwenden
Der Schlüsseltyp, den Sie zum Wechseln zwischen Zielen verwenden, ist NavController.
Weitere Informationen zur Klasse selbst und zum Erstellen einer Instanz davon finden Sie unter Navigationscontroller erstellen. In diesem Leitfaden wird beschrieben, wie Sie das Tool verwenden.
Navigieren
Unabhängig davon, welches UI-Framework Sie verwenden, gibt es eine einzelne Funktion, mit der Sie zu einem Ziel navigieren können: NavController.navigate().
Für navigate() sind viele Überladungen verfügbar. Die Überlastung, die Sie auswählen sollten, hängt von Ihrem genauen Kontext ab. Sie sollten beispielsweise einen Overload verwenden, wenn Sie zu einem Composable navigieren, und einen anderen, wenn Sie zu einer Ansicht navigieren.
In den folgenden Abschnitten werden einige der wichtigsten navigate()-Überladungen beschrieben, die Sie verwenden können.
Zu einem Composable wechseln
Verwenden Sie NavController.navigate<T>, um zu einem Composable zu navigieren.
Bei dieser Überladung akzeptiert navigate() ein einzelnes route-Argument, für das Sie einen Typ übergeben. Sie dient als Schlüssel für ein Ziel.
@Serializable
object FriendsList
navController.navigate(route = FriendsList)
Wenn Sie zu einem Composable im Navigationsdiagramm navigieren möchten, müssen Sie zuerst NavGraph so definieren, dass jedes Ziel einem Typ entspricht. Bei Composables verwenden Sie dazu die Funktion composable().
Ereignisse aus Ihren komponierbaren Funktionen verfügbar machen
Wenn eine zusammensetzbare Funktion zu einem neuen Bildschirm navigieren muss, sollten Sie ihr keine Referenz auf NavController übergeben, damit sie navigate() direkt aufrufen kann.
Gemäß den Prinzipien des unidirektionalen Datenflusses (UDF) sollte die zusammensetzbare Funktion stattdessen ein Ereignis bereitstellen, das von NavController verarbeitet wird.
Genauer gesagt sollte Ihr Composable einen Parameter vom Typ () -> Unit haben.
Wenn Sie Ihrem NavHost mit der Funktion composable() Ziele hinzufügen, übergeben Sie Ihrem Composable einen Aufruf von NavController.navigate().
Ein Beispiel dafür finden Sie im folgenden Unterabschnitt.
beschrieben verfügbar machen.Beispiel
Das folgende Snippet veranschaulicht die oben beschriebenen Punkte:
- Jedes Ziel im Diagramm wird mit einer Route erstellt. Eine Route ist ein serialisierbares Objekt oder eine serialisierbare Klasse, die die für das Ziel erforderlichen Daten beschreibt.
- Die
MyAppNavHost-Composable enthält dieNavController-Instanz. - Entsprechend sollten Aufrufe von
navigate()dort und nicht in einer untergeordneten Composable wieProfileScreenerfolgen. ProfileScreenenthält einen Button, über den der Nutzer bei einem Klick zuFriendsListweitergeleitet wird.navigate()wird jedoch nicht direkt aufgerufen.- Stattdessen ruft die Schaltfläche eine Funktion auf, die als Parameter
onNavigateToFriendsverfügbar ist. - Wenn
MyAppNavHostdem NavigationsdiagrammProfileScreenhinzufügt, wird füronNavigateToFriendseine Lambda-Funktion übergeben, dienavigate(route = FriendsListaufruft. - So wird sichergestellt, dass der Nutzer beim Drücken der Schaltfläche
ProfileScreenkorrekt zuFriendsListScreenweitergeleitet wird.
@Serializable
object Profile
@Serializable
object FriendsList
@Composable
fun MyAppNavHost(
modifier: Modifier = Modifier,
navController: NavHostController = rememberNavController(),
) {
NavHost(
modifier = modifier,
navController = navController,
startDestination = Profile
) {
composable<Profile> {
ProfileScreen(
onNavigateToFriends = { navController.navigate(route = FriendsList) },
/*...*/
)
}
composable<FriendsList> { FriendsListScreen(/*...*/) }
}
}
@Composable
fun ProfileScreen(
onNavigateToFriends: () -> Unit,
/*...*/
) {
/*...*/
Button(onClick = onNavigateToFriends) {
Text(text = "See friends list")
}
}
Navigation mit einer Ganzzahl-ID
Wenn Sie mit einer Ganzzahl-ID zu einem Ziel navigieren möchten, rufen Sie die Überladung navigate(int) auf. Sie akzeptiert die Ressourcen-ID einer Aktion oder eines Ziels. Das folgende Code-Snippet zeigt, wie Sie diese Überladung verwenden können, um zur ViewTransactionsFragment zu navigieren:
Kotlin
viewTransactionsButton.setOnClickListener { view ->
view.findNavController().navigate(R.id.viewTransactionsAction)
}
Java
viewTransactionsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Navigation.findNavController(view).navigate(R.id.viewTransactionsAction);
}
});
Wenn Sie IDs für die Navigation verwenden, sollten Sie nach Möglichkeit Aktionen verwenden. Aktionen liefern zusätzliche Informationen in Ihrem Navigationsdiagramm und zeigen visuell, wie Ihre Ziele miteinander verbunden sind.
Navigation mit NavDeepLinkRequest
Verwenden Sie die Überladung navigate(NavDeepLinkRequest), um zu einem impliziten Deeplink-Ziel zu navigieren. Das folgende Snippet enthält eine Implementierung dieser Methode:
Kotlin
val request = NavDeepLinkRequest.Builder
.fromUri("android-app://androidx.navigation.app/profile".toUri())
.build()
findNavController().navigate(request)
Java
NavDeepLinkRequest request = NavDeepLinkRequest.Builder
.fromUri(Uri.parse("android-app://androidx.navigation.app/profile"))
.build()
NavHostFragment.findNavController(this).navigate(request)
Im Gegensatz zur Navigation mit Aktions- oder Ziel-IDs können Sie zu jedem Deeplink in Ihrem Diagramm navigieren, unabhängig davon, ob das Ziel sichtbar ist. Sie können zu einem Ziel im aktuellen Diagramm oder zu einem Ziel in einem völlig anderen Diagramm navigieren.
Aktionen und MIME-Typen
Zusätzlich zu Uri unterstützt NavDeepLinkRequest auch Deeplinks mit Aktionen und MIME-Typen. Wenn Sie der Anfrage eine Aktion hinzufügen möchten, verwenden Sie fromAction() oder setAction(). Verwenden Sie fromMimeType() oder setMimeType(), um einer Anfrage einen MIME-Typ hinzuzufügen.
Damit ein NavDeepLinkRequest mit einem Ziel für implizite Deeplinks übereinstimmt, müssen URI, Aktion und MIME-Typ mit dem NavDeepLink im Ziel übereinstimmen. URIs müssen mit dem Muster übereinstimmen, die Aktionen müssen exakt übereinstimmen und die MIME-Typen müssen verwandt sein. Beispiel: image/jpg stimmt mit image/\* überein.
Weitere Kontexte
In diesem Dokument wird beschrieben, wie Sie NavController.navigate() in den häufigsten Anwendungsfällen verwenden. Die Funktion hat jedoch eine Reihe von Überladungen, die Sie in verschiedenen Kontexten und in Verbindung mit einem beliebigen UI-Framework verwenden können. Weitere Informationen zu diesen Überladungen finden Sie in der Referenzdokumentation.
Weitere Informationen
Weitere Informationen finden Sie auf den folgenden Seiten:
- Navigations-Controller erstellen
- Navigation und Backstack
- Mit Optionen navigieren
- Typsicherheit in Kotlin DSL und Navigation Compose