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.
1
setContent {
2
TabNavigator(HomeTab) {
3
// ...
4
}
5
}
Copied!
But now, the HomeTab will have it's own Navigator.
1
object HomeTab : Screen {
2
3
@Composable
4
override fun Content() {
5
Navigator(PostListScreen())
6
}
7
}
Copied!
That way, we can use the LocalNavigator to navigate deeper into HomeTab, or the LocalTabNavigator to switch between tabs.
1
class PostListScreen : Screen {
2
3
@Composable
4
private fun GoToPostDetailsScreenButton(post: Post) {
5
val navigator = LocalNavigator.currentOrThrow
6
7
Button(
8
onClick = { navigator.push(PostDetailsScreen(post.id)) }
9
)
10
}
11
12
@Composable
13
private fun GoToProfileTabButton() {
14
val tabNavigator = LocalTabNavigator.current
15
16
Button(
17
onClick = { tabNavigator.current = ProfileTab }
18
)
19
}
20
}
Copied!

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).
1
setContent {
2
Navigator(ScreenA) { navigator0 ->
3
println(navigator.level)
4
// 0
5
println(navigator.parent == null)
6
// true
7
Navigator(ScreenB) { navigator1 ->
8
println(navigator.level)
9
// 1
10
println(navigator.parent == navigator0)
11
// true
12
Navigator(ScreenC) { navigator2 ->
13
println(navigator.level)
14
// 2
15
println(navigator.parent == navigator1)
16
// true
17
}
18
}
19
}
20
}
Copied!
Another operation is the popUntilRoot(), it will recursively pop all screens starting from the leaf navigator until the root one.

Sample

Source code here.
Last modified 3mo ago