Sie können integrierte typsichere APIs verwenden, um Typsicherheit zur Kompilierzeit für Ihren Navigationsgraphen zu gewährleisten. Diese APIs sind verfügbar, wenn Ihre App Navigation Compose oder Navigation Kotlin DSL verwendet. Sie sind ab dem Navigation
2.8.0 verfügbar.
Diese APIs entsprechen dem, was Safe Args für Navigationsgraphen bietet, die mit XML erstellt wurden.
Routen definieren
Wenn Sie typsichere Routen in Compose verwenden möchten, müssen Sie zuerst serialisierbare Klassen oder Objekte definieren, die Ihre Routen darstellen.
Verwenden Sie die Annotation @Serializable, die vom Kotlin Serialization-Plug-in bereitgestellt wird, um serialisierbare Objekte zu definieren.
Dieses Plug-in kann Ihrem Projekt hinzugefügt werden, indem Sie diese Abhängigkeiten hinzufügen.
Anhand der folgenden Regeln können Sie entscheiden, welcher Typ für Ihre Route verwendet werden soll:
- Objekt: Verwenden Sie ein Objekt für Routen ohne Argumente.
- Klasse: Verwenden Sie eine Klasse oder Datenklasse für Routen mit Argumenten.
KClass<T>: Verwenden Sie diese Option, wenn Sie keine Argumente übergeben müssen, z. B. für eine Klasse ohne Parameter oder eine Klasse, in der alle Parameter Standardwerte haben.- Beispiel:
Profile::class
- Beispiel:
In allen Fällen muss das Objekt oder die Klasse serialisierbar sein.
Beispiel:
// Define a home route that doesn't take any arguments
@Serializable
object Home
// Define a profile route that takes an ID
@Serializable
data class Profile(val id: String)
Diagramm erstellen
Als Nächstes müssen Sie das Navigationsdiagramm definieren. Verwenden Sie die Funktion composable(), um kombinierbare Funktionen als Ziele in Ihrem Navigationsdiagramm zu definieren.
NavHost(navController, startDestination = Home) {
composable<Home> {
HomeScreen(onNavigateToProfile = { id ->
navController.navigate(Profile(id))
})
}
composable<Profile> { backStackEntry ->
val profile: Profile = backStackEntry.toRoute()
ProfileScreen(profile.id)
}
}
In diesem Beispiel ist Folgendes zu beachten:
composable()akzeptiert einen Typparameter. Der Wert istcomposable<Profile>.- Das Definieren des Zieltyps ist ein robusterer Ansatz als das Übergeben eines
route-Strings wie incomposable("profile"). - Die Routenklasse definiert den Typ jedes Navigationsarguments, wie in
val id: String. Daher istNavArgumentnicht erforderlich. - Für die Profilroute wird mit der Erweiterungsmethode
toRoute()dasProfile-Objekt aus demNavBackStackEntryund seinen Argumenten neu erstellt.
Weitere Informationen zum Entwerfen des Navigationsdiagramms finden Sie auf der Seite Navigationsdiagramm entwerfen.
Auf Argumente in einem ViewModel zugreifen
Wenn Sie in einem ViewModel auf Argumente einer typsicheren Route zugreifen möchten, können Sie die Route aus dem SavedStateHandle abrufen, indem Sie SavedStateHandle.toRoute<T>() aufrufen, wobei T Ihre Routenklasse ist:
class ProfileViewModel(
savedStateHandle: SavedStateHandle
) : ViewModel() {
private val profile = savedStateHandle.toRoute<Profile>()
private val userInfo: Flow<UserInfo> = userInfoRepository.getUserInfo(profile.id)
}
Typensichere Route aufrufen
Schließlich können Sie mit der Funktion navigate() zur komponierbaren Funktion navigieren, indem Sie die Instanz der Route übergeben:
navController.navigate(Profile(id = 123))
Der Nutzer wird zum Ziel composable<Profile> im Navigationsdiagramm weitergeleitet. Alle Navigationsargumente, z. B. id, können abgerufen werden, indem Profile mit NavBackStackEntry.toRoute rekonstruiert und die zugehörigen Eigenschaften gelesen werden.