Reputation: 4532
I'm trying to implement a multiple navigation controller
with multiple back stack BottomNavigationView
, as per the github examples. However, the example uses a different nav graph for each tab, which makes things easy. In my case I need to use the same nav graph for all of my tabs, but with different start destinations, than the "home destination" set in the nav graph.
So far I've managed to modify the NavigationExtensions
file in order to achieve the single navgraph for all tabs, and I get multiple navControllers
with their own back stacks, but I cannot figure out how to start a nav graph at a different destination.
I've tried using .navigate
when getting the navcontroller, but since it's not yet attached, it does not work. Any ideas on how to achieve this? Thank you.
Upvotes: 24
Views: 22292
Reputation: 6996
I wrote two extensions to do the job. First is to be used to change destination in the current node. The second is to be used to traverse multiple times into nested graphs
_main_graph
|
|_nested_graph_1
|
|_nested_graph_2
|
|_nested_graph_3
|
|_nested_graph_4
|
|_change this destination!!!!
fun NavController.changeNodeDestination(nodeId: Int, destinationId: Int): NavController {
val graph = graph.findNode(nodeId) as NavGraph
graph.startDestination = destinationId
return this
}
fun NavController.changeNodeDestination(vararg nodeIds: Int, destinationId: Int): NavController {
var currentNode = graph
nodeIds.forEachIndexed { index, i ->
currentNode = currentNode.findNode(nodeIds[index]) as NavGraph
}
currentNode.startDestination = destinationId
return this
}
Usage:
findNavController().changeNodeDestination(
R.id.navigation_login,
R.id.nav_change_password, // GO two levels inside nested graphs
destinationId = startDestination
).navigate(navID, bundle)
Upvotes: 10
Reputation: 2029
We had a requirement wherein the displayed start screen would depend if the user has logged on, what we did was the following:
XML
if it exists<fragment>
tag: app:defaultNavHost="true"
and app:navGraph
On our main Activity's onCreate()
, we create a NavGraph
object :
NavController navController = Navigation.findNavController(this, R.id.your_nav_hostfragment);
NavGraph navGraph = navController.getNavInflater().inflate(R.navigation.your_navigation_xml);
Then depending on your requirement, you can set the start destination on the NavGraph using setStartDestination, then apply the NavGraph to the NavController:
if (condition) {
navGraph.setStartDestination(R.id.screen1);
} else {
navGraph.setStartDestination(R.id.screen2);
}
navController.setGraph(navGraph);
Upvotes: 62