My team raised me a question regarding compose nav...
# compose
a
My team raised me a question regarding compose navigation and deeplinks which I was not able to answer. Let’s say we have 2 independent feature modules, A and B. a screen from A can navigate to a screen from B. I call the nav graph of B from the top-level module so it has access to the B’s Screen composables, without having A depend directly on B. We would like a deep link navigation to B with a simulated backstack as if B was opened from a screen in A. Is this possible with this kind of setup?
While writing this question I had the idea of doing two navigation calls something like
Copy code
navController.navigate("screen_in_A")
navController.navigate("screen_in_B")
Will this work? Edit: 🤦 forgot we’re talking deeplinks here, so this idea is stupid
i
The synthetic back stack you get when deep linking is built from the start destination(s) of your graphs, as per the docs: https://developer.android.com/guide/navigation/navigation-deep-link#implicit
So if A is the start destination of your graph, it will be on the back stack
a
Yes, it’s easy when working in a single module since I could do
Copy code
navigation("main") {
  composable("top") { TopScreen() }

  navigation("A") {
    composable("screen_in_a") { ScreenInA() }

    navigation("B") {
       composable("screen_in_b) {
          ScreenInB()
       }
    }
  }
}
If I understand this correctly.
B got complex so we separated it out on its own feature module. Now the graph looks like
Copy code
navigation("main") {
  composable("top") { TopScreen() }

  navigationA() // defined in feature_a module
  
  navigationB() // defined in feature_b module
}
so from within A we can still call
navController.navigate("screen_in_b")
without coupling module A with B
Maybe I could hoist the actual composable like this…
Copy code
navigation("main") {
  navigationA(
      screenInB = {
          ActualScreenInB()
      }
  )
}

// feature a
fun NavGraphBuilder.navigationA(
  screenInB: () -> Unit,
) {
  navigation("A") {
     composable("screen_in_a") { ScreenInA()
     navigation("B") {
       screenInB()
     }
  }
}
i
Why wouldn't your
navigationA()
just take a
embeddedGraph: NavGraphBuilder.() -> Unit
? Then you could do
navigationA(navigationB())
If
navigation("B")
really is a subgraph of
navigation("A")
, then your graph structure should represent that
a
Wow…
I simply didn’t think of that 😓
then your graph structure should represent that
Yeah! I was thinking of this too, having two nav graphs at the same level doesn’t seem right, I use that kind of pattern more for global/shared navigations. I just never thought I could just pass the graph directly… Thanks Ian!