Links
Comment on page

Nested navigation

TabNavigator + Navigator

For more complex use cases, when each tab should have its own independent navigation, like the Youtube app, you can combine the TabNavigator with multiple Navigators.
Let's go back to the Tab navigation example.
setContent {
TabNavigator(HomeTab) {
// ...
}
}
But now, the HomeTab will have it's own Navigator.
object HomeTab : Screen {
@Composable
override fun Content() {
Navigator(PostListScreen())
}
}
That way, we can use the LocalNavigator to navigate deeper into HomeTab, or the LocalTabNavigator to switch between tabs.
class PostListScreen : Screen {
@Composable
private fun GoToPostDetailsScreenButton(post: Post) {
val navigator = LocalNavigator.currentOrThrow
Button(
onClick = { navigator.push(PostDetailsScreen(post.id)) }
)
}
@Composable
private fun GoToProfileTabButton() {
val tabNavigator = LocalTabNavigator.current
Button(
onClick = { tabNavigator.current = ProfileTab }
)
}
}

Nested Navigators

Going a little further, it's possible to have nested navigators. The Navigator has a level property (so you can check how deeper your are) and can have a parent navigator (if you need to interact with it).
setContent {
Navigator(ScreenA) { navigator0 ->
println(navigator.level)
// 0
println(navigator.parent == null)
// true
Navigator(ScreenB) { navigator1 ->
println(navigator.level)
// 1
println(navigator.parent == navigator0)
// true
Navigator(ScreenC) { navigator2 ->
println(navigator.level)
// 2
println(navigator.parent == navigator1)
// true
}
}
}
}
Another operation is the popUntilRoot(), it will recursively pop all screens starting from the leaf navigator until the root one.

Sample

Source code here.