1

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?

1 Answer 1

2

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.