Die Navigationskomponente 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. Er 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 Composables 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 (Unidirectional Data Flow, 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 vorherigen Abschnitte:
- 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 zusammensetzbaren Funktion wieProfileScreenerfolgen. ProfileScreenenthält einen Button, über den der Nutzer durch Klicken 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 dafür gesorgt, dass der Nutzer beim Drücken des Buttons
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 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.
Mit Compose in einer Fragment-basierten App navigieren
Wenn Sie Jetpack Compose in einer fragmentbasierten Navigationsarchitektur verwenden (z. B. in einer App mit gemischten Ansichten und Compose), können Sie keine typsicheren Compose-Routen für die direkte Navigation verwenden. Stattdessen müssen Sie in Ihrem XML-Navigationsdiagramm definierte Ganzzahl-IDs (Aktionen) verwenden.
Wenn Sie Ziele über Compose-Code ändern möchten, müssen Sie ein Ereignis (Lambda) aus Ihrer Composable-Funktion verfügbar machen:
@Composable
fun MyScreen(onNavigateToProfile: () -> Unit) {
Button(onClick = { onNavigateToProfile() }) {
Text("Go to Profile")
}
}
Im Fragment überbrücken Sie Compose und die Fragment-basierte Navigationskomponente, indem Sie die NavController des Fragments aufrufen, wenn das Ereignis ausgelöst wird:
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return ComposeView(requireContext()).apply {
setContent {
MyScreen(onNavigateToProfile = { findNavController().navigate(R.id.nav_profile) })
}
}
}
Dieser Ansatz sorgt dafür, dass Ihre Composables wiederverwendbar und testbar bleiben, da sie nicht direkt von der NavController des Fragments abhängen.
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