Reputation: 16273
I am implementing navigation in a Compose App using the guides:
So, instead of using string routes, I use objects as suggested. However, I am bit confused how to add navigation screens with route arguments. I know it's more a Kotlin question than Android / Compose.
I have written this:
@Serializable
sealed class NavigationScreen (
@StringRes val nameResourceId: Int,
@DrawableRes val iconResourceId: Int
) {
@Serializable
data object SignIn: NavigationScreen( R.string.sign_in, R.drawable.baseline_person_24)
@Serializable
data object Home: NavigationScreen( R.string.home, R.drawable.baseline_home_24)
@Serializable
data object Settings: NavigationScreen(R.string.settings, R.drawable.baseline_settings_24)
}
The above sealed class works well but doesn't hold route arguments. Is there a clean way to add them?
Upvotes: 1
Views: 519
Reputation: 6952
Route arguments in typesafe navigation are provided as data class properties. Passing an user id to your SignIn screen would look like:
@Serializable
data class SignIn(val userId: Int): NavigationScreen( R.string.sign_in, R.drawable.baseline_person_24)
In your NavHost you don't need to provide a route string anymore, all you need to specify is your navigation type e.g. SignIn:
NavHost(navController, startDestination = Home) {
composable<Home> {
HomeScreen(onNavigateToSignIn = { userId ->
navController.navigate(SignIn(userId))
})
}
composable<SignIn> { backStackEntry ->
val signIn: SignIn = backStackEntry.toRoute()
SignInScreen(signIn)
}
}
Now you can use the extension method NavBackStackEntry.toRoute()
to create your navigation type. This type can also be accessed in ViewModels via SavedStateHandle.toRoute()
.
Here you can find an in depth explanation about typesafe navigation
Upvotes: 2