From the docs, I see you can nest navigation graphs like so:
NavHost(navController, startDestination = "home") {
...
// Navigating to the graph via its route ('login') automatically
// navigates to the graph's start destination - 'username'
// therefore encapsulating the graph's internal routing logic
navigation(startDestination = "username", route = "login") {
composable("username") { ... }
composable("password") { ... }
composable("registration") { ... }
}
...
}
I am wondering, how would one pass an argument in the route, and make that available to all composables inside the nav graph?
Here's my current nav graph:
navigation(
// I'd like to grab this parameter
route = "dashboard?classId={classId}",
startDestination = Route.ScreenOne.route) {
composable(Route.ScreenOne.route) {
// And then pass the parameter here, or to any composable below
ScreenOne(classId)
}
composable(Route.ScreenTwo.route) {
ScreenTwo()
}
composable(Route.ScreenThree.route) {
ScreenThree()
}
}
I am basically trying to avoid setting the classId navigation argument individually on each composable route. I didn't see a way to pass a list of arguments to navigation() like you can in a composable().
It might be that what I am describing isn't possible, but looking forward to anyone's thoughts!
UPDATE: 6th April 2023 - Previously my answer was broken. I've now updated this to get the back stack entry from the nav controller. This solution now works.
Yes, this is perfectly possible - took me a while as the documentation is lacking (they explain Navigation arguments, and Nested Graphs, but not both!).
You will need access to your navController to do this.
You call getBackStackEntry on the navController to get the top most entry. It will need wrapping inside a remember(entry) { } block as you are calling it inside a Composable.
private fun NavGraphBuilder.yourNestedGraph(navController: NavHostController) {
navigation(
route = "dashboard?classId={classId}",
startDestination = "yourStartDestination",
arguments = listOf(navArgument("classId") { type = NavType.StringType })
) {
composable(route = "yourStartDestination") { entry ->
val parentEntry = remember(entry) { navController.getBackStackEntry("dashboard?classId={classId}") }
val classId = parentEntry.arguments?.getString("classId")
YourScreenComposable(classId)
}
composable(route = "someOtherNestedRoute") { entry ->
val parentEntry = remember(entry) { navController.getBackStackEntry("dashboard?classId={classId}") }
val classId = parentEntry.arguments?.getString("classId")
AnotherScreen(classId)
}
composable(route = "andAnotherNestedRoute") { entry ->
val parentEntry = remember(entry) { navController.getBackStackEntry("dashboard?classId={classId}") }
val classId = parentEntry.arguments?.getString("classId")
AndAnotherScreen(classId)
}
}
}
** Important Note ** - You may need to type the navigation function again and import it - similar to the issue mentioned in the question, I also couldn't see an arguments parameter at first in my existing navigation functions, but when I typed out navigation again inside my NavGraphBuilder I saw the other option which did have the arguments parameter.
You can access the graph arguments from child composables:
navController.getBackStackEntry("dashboard?classId={classId}").arguments?.getString("classId")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With