Jetpack Compose Navigation: How do I navigate between composables of a nested nav graph?

520 views Asked by At

Consider the following Jetpack Compose Navigation graph:

<root>
  a
    x
    y
  b
    x
    y

Here, a and b are nested nav graphs created using navigation(startDestination = "x", route = ROUTE) where ROUTE is a or b respectively. Both of these nested nav graphs have composables x and y inside them.

Let's assume we're currently in route b/y, that is the screen y inside nested nav graph b. The user wants to navigate to b/x. I tried this by calling navController.navigate("x"), having assumed that it would first search the nested graph the user is currently in (b). But it turns out that Compose Navigation scans the full nav graph top to bottom for a composable matching x, so it finds a/x.

What call to navController.navigate(...) do I have to make to navigate from b/y to b/x?

Here's the full sample:

NavHost(navController, startDestination = "b") {
    navigation(startDestination = "x", route = "a") {
        composable("x") {
            Text(text = "We're in a/x")
            Button(onClick = { navController.navigate("y") }) {
                Text("Go to y")
            }
        }
        composable("y") {
            Text(text = "We're in a/y")
            Button(onClick = { navController.navigate("x") }) {
                Text("Go to x")
            }
        }
    }
    navigation(startDestination = "y", route = "b") {
        composable("x") {
            Text(text = "We're in b/x")
            Button(onClick = { navController.navigate("y") }) {
                Text("Go to y")
            }
        }
        composable("y") {
            Text(text = "We're in b/y")
            Button(onClick = { navController.navigate("x") }) {
                Text("Go to x")
            }
        }
    }
}
1

There are 1 answers

1
Laxmi kant On

I have added the parent graph's route ("a" or "b") before specifying the child graph's route ("x" or "y") when navigating between composables. This is essential because each nested graph is treated as a separate stack of composables.

        NavHost(navController, startDestination = "b") {
            navigation(startDestination = "x", route = "a") {
                composable("x") {
                    Text(text = "We're in a/x")
                    Button(onClick = { navController.navigate("a/y") }) {
                        Text("Go to a/y")
                    }
                }
                composable("y") {
                    Text(text = "We're in a/y")
                    Button(onClick = { navController.navigate("a/x") }) {
                        Text("Go to a/x")
                    }
                }
            }
            navigation(startDestination = "x", route = "b") {
                composable("x") {
                    Text(text = "We're in b/x")
                    Button(onClick = { navController.navigate("b/y") }) {
                        Text("Go to b/y")
                    }
                }
                composable("y") {
                    Text(text = "We're in b/y")
                    Button(onClick = { navController.navigate("b/x") }) {
                        Text("Go to b/x")
                    }
                }
            }
        }