Type-safe navigation with a single source of truth.
// NavGraph.kt
@Composable
fun NavGraph(startDestination: String = "home") {
val nav = rememberNavController()
NavHost(navController = nav, startDestination = startDestination) {
composable("home") { HomeScreen(onDetails = { id -> nav.navigate("details/$id") }) }
composable("details/{id}", arguments = listOf(navArgument("id") { type = NavType.StringType })) { backStack ->
val id = backStack.arguments?.getString("id")!!
DetailsScreen(id)
}
}
}
@Serializable
with kotlinx.serialization
and helpers for safer args.Two screens + NavHost + typed argument extraction.
// ui/NavGraph.kt
@Composable
fun NavGraph() {
val nav = rememberNavController()
NavHost(navController = nav, startDestination = "home") {
composable("home") { HomeScreen(onOpen = { id -> nav.navigate("details/$id") }) }
composable("details/{id}", arguments = listOf(navArgument("id") { type = NavType.StringType })) { backStack ->
val id = requireNotNull(backStack.arguments?.getString("id"))
DetailsScreen(id)
}
}
}
// ui/HomeScreen.kt
@Composable
fun HomeScreen(onOpen: (String) -> Unit) { Column { Text("Home"); Button({ onOpen("42") }) { Text("Open 42") } } }
// ui/DetailsScreen.kt
@Composable
fun DetailsScreen(id: String) { Text("Details for $id") }
Notes
Route
object with build(id)
and parse(backStackEntry)
helpers.Paste into Android Studio project (see sandboxes/android-compose):