Tab navigation¶
Before reading this section it is advised to have read Advanced navigation.
To set up tab navigation, simply implement the Tab
interface for a data class or object.
A Tab
needs to have its own distinct index, and it’s also a screen in itself.
For example, like a Screen
, it also has a Content
function that is used for displaying its contents.
data object HomeTab : Tab {
override val index: UInt = 0u
@Composable
override fun Content() {
// ...
}
}
data object ProfileTab : Tab {
override val index: UInt = 1u
@Composable
override fun Content() {
// ...
}
}
Tabs, just like screens need to exist within a Navigator
. But instead of CurrentScreen
they need to be rendered
with CurrentTab
.
You would most likely want to manage tabs within a Scaffold
).
Let’s create a Navigator
that manages tabs inside one.
@Composable
fun App(){
Navigator(HomeTab) { navigator ->
Scaffold(
content = {
CurrentTab(navigator)
},
bottomBar = {
NavigationBar {
TabNavigationItem(HomeTab)
TabNavigationItem(ProfileTab)
}
}
)
}
}
@Composable
private fun RowScope.TabNavigationItem(tab: Tab) {
val navigator = LocalNavigator.currentOrThrow
val icon = when (tab.index) {
0u -> rememberVectorPainter(Icons.Default.Home)
1u -> rememberVectorPainter(Icons.Default.Person)
else -> return
}
val title = when (tab.index) {
0u -> "Home"
2u -> "Profile"
else -> return
}
NavigationBarItem(
selected = navigator.current == tab,
onClick = { navigator.current = tab },
icon = { Icon(painter = icon, contentDescription = title) }
)
}
Tabs never get disposed until the screen owning the navigator they are in gets disposed.
You can find source code for a working example here.