commonMain.ru.alexgladkov.odyssey.compose.base.BottomBarNavigator.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of odyssey-compose Show documentation
Show all versions of odyssey-compose Show documentation
Lightweight multiplatform navigation library (jvm, android, ios)
package ru.alexgladkov.odyssey.compose.base
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
import androidx.compose.ui.Modifier
import ru.alexgladkov.odyssey.compose.controllers.MultiStackRootController
import ru.alexgladkov.odyssey.compose.controllers.TabNavigationModel
import ru.alexgladkov.odyssey.compose.local.LocalRootController
import ru.alexgladkov.odyssey.compose.navigation.bottom_bar_navigation.BottomNavConfiguration
import ru.alexgladkov.odyssey.compose.navigation.bottom_bar_navigation.TopNavConfiguration
import ru.alexgladkov.odyssey.core.toScreenBundle
@Composable
fun TabNavigator(
modifier: Modifier = Modifier,
startScreen: String?,
currentTab: TabNavigationModel
) {
val configuration = currentTab.rootController.currentScreen.collectAsState()
val saveableStateHolder = rememberSaveableStateHolder()
saveableStateHolder.SaveableStateProvider(currentTab.tabInfo.tabItem.name) {
Box(modifier = modifier) {
CompositionLocalProvider(
LocalRootController provides currentTab.rootController
) {
configuration.value?.let { navConfig ->
AnimatedHost(
currentScreen = navConfig.screen.toScreenBundle(),
animationType = navConfig.screen.animationType,
screenToRemove = navConfig.screenToRemove?.toScreenBundle(),
isForward = navConfig.screen.isForward,
onScreenRemove = currentTab.rootController.onScreenRemove
) {
val rootController = currentTab.rootController
rootController.renderScreen(it.realKey, it.params)
}
}
}
}
}
LaunchedEffect(currentTab) {
currentTab.rootController.drawCurrentScreen(startScreen = startScreen)
}
}
@Composable
fun BottomBarNavigator(startScreen: String?) {
val rootController = LocalRootController.current as MultiStackRootController
val tabItem = rootController.stackChangeObserver.collectAsState().value ?: return
val bottomNavConfiguration =
rootController.tabsNavModel.navConfiguration as BottomNavConfiguration
Column(modifier = Modifier.fillMaxSize()) {
TabNavigator(modifier = Modifier.weight(1f), startScreen, tabItem)
BottomNavigation(
backgroundColor = bottomNavConfiguration.backgroundColor,
elevation = bottomNavConfiguration.elevation
) {
rootController.tabItems.forEach { currentItem ->
val configuration = currentItem.tabInfo.tabItem.configuration
val position = rootController.tabItems.indexOf(currentItem)
val isSelected = tabItem == currentItem
BottomNavigationItem(
selected = isSelected,
selectedContentColor = configuration.selectedColor
?: bottomNavConfiguration.selectedColor,
unselectedContentColor = configuration.unselectedColor
?: bottomNavConfiguration.unselectedColor,
icon = {
if (isSelected) {
configuration.selectedIcon?.let {
Icon(
painter = it,
contentDescription = configuration.title
)
}
} else {
configuration.unselectedIcon?.let {
Icon(
painter = it,
contentDescription = configuration.title
)
}
}
},
label = {
Text(
text = configuration.title,
style = configuration.titleStyle ?: LocalTextStyle.current
)
},
onClick = {
rootController.switchTab(position)
})
}
}
}
rootController.tabsNavModel.launchedEffect.invoke()
}
@Composable
fun TopBarNavigator(startScreen: String?) {
val rootController = LocalRootController.current as MultiStackRootController
val tabItem = rootController.stackChangeObserver.collectAsState().value ?: return
val bottomNavConfiguration = rootController.tabsNavModel.navConfiguration as TopNavConfiguration
Column(modifier = Modifier.fillMaxSize()) {
TabRow(
backgroundColor = bottomNavConfiguration.backgroundColor,
contentColor = bottomNavConfiguration.contentColor,
selectedTabIndex = rootController.tabItems.indexOfFirst { it == tabItem }
.coerceAtLeast(0)
) {
rootController.tabItems.forEach { currentItem ->
val configuration = currentItem.tabInfo.tabItem.configuration
val position = rootController.tabItems.indexOf(currentItem)
val isSelected = tabItem == currentItem
Tab(
selected = isSelected,
onClick = { rootController.switchTab(position) },
text = {
Text(
text = configuration.title,
style = configuration.titleStyle ?: LocalTextStyle.current
)
}
)
}
}
TabNavigator(modifier = Modifier.weight(1f), startScreen, tabItem)
}
rootController.tabsNavModel.launchedEffect.invoke()
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy