Tab navigation
To use the TabNavigator you should first import cafe.adriel.voyager:voyager-tab-navigator (see Setup).
Voyager provides a specialized navigator for tabs : the TabNavigator.
The Tab interface, like the Screen, has a Content() composable function, but also requires a TabOptions.
1
object HomeTab : Tab {
2
3
override val options: TabOptions
4
@Composable
5
get() {
6
val title = stringResource(R.string.home_tab)
7
val icon = rememberVectorPainter(Icons.Default.Home)
8
9
return remember {
10
TabOptions(
11
index = 0u,
12
title = title,
13
icon = icon
14
)
15
}
16
}
17
18
@Composable
19
override fun Content() {
20
// ...
21
}
22
}
Copied!
Since tabs aren't usually reused, its OK to create them as object.
The TabNavigator unlike the Navigator:
  • Don't handle back presses, because the tabs are siblings
  • Don't implements the Stack API, just provides a current property
You can use it with a Scaffold to easily create the UI for your tabs.
1
setContent {
2
TabNavigator(HomeTab) {
3
Scaffold(
4
content = {
5
CurrentTab()
6
},
7
bottomBar = {
8
BottomNavigation {
9
TabNavigationItem(HomeTab)
10
TabNavigationItem(FavoritesTab)
11
TabNavigationItem(ProfileTab)
12
}
13
}
14
)
15
}
16
}
Copied!
Like theCurrentScreen(), you should use CurrentTab instead of tabNavigator.current.Content(), because it will save the Tab's subtree for you (see SaveableStateHolder).
Use the LocalTabNavigator to get the current TabNavigator, and current to get and set the current tab.
1
@Composable
2
private fun RowScope.TabNavigationItem(tab: Tab) {
3
val tabNavigator = LocalTabNavigator.current
4
5
BottomNavigationItem(
6
selected = tabNavigator.current == tab,
7
onClick = { tabNavigator.current = tab },
8
icon = { Icon(painter = tab.icon, contentDescription = tab.title) }
9
)
10
}
Copied!

Sample

Source code here.
Last modified 3mo ago
Copy link
Contents
Sample