I have a NavigationBar
with a NavHost
containing two destinations:
@Serializable
object Training
@Serializable
object Statistics
data class TopLevelRoute<T : Any>(val name: String, val route: T, val icon: ImageVector)
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun HomeScreen() {
val topLevelRoutes = listOf(
TopLevelRoute("Training", Training, Icons.Default.Lightbulb),
TopLevelRoute("Statistics", Statistics, Icons.Default.AutoGraph)
)
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
val navController = rememberNavController()
Scaffold(
modifier = Modifier
.fillMaxSize()
.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
CenterAlignedTopAppBar(
scrollBehavior = scrollBehavior,
title = {
Text("Title")
}
)
},
bottomBar = {
NavigationBar {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
topLevelRoutes.forEach { topLevelRoute ->
NavigationBarItem(
icon = { Icon(topLevelRoute.icon, contentDescription = topLevelRoute.name) },
label = { Text(topLevelRoute.name) },
selected = currentDestination?.hierarchy?.any { it.hasRoute(topLevelRoute.route::class) } == true,
onClick = {
navController.navigate(topLevelRoute.route) {
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
}
)
}
}
}
) { innerPadding ->
NavHost(navController, startDestination = Training, Modifier.padding(innerPadding)) {
composable<Training> {
Text("Training")
}
composable<Statistics> {
StatisticsScreen()
}
}
}
}
@Composable
fun StatisticsScreen() {
LazyColumn {
items(50) {
Text(modifier = Modifier.fillMaxWidth(), text = "Item $it")
}
}
}
I am using a pinnedScrollBehavior
so that the CenterAlignedTopAppBar
is lifted once the content below it scrolls. The issue that I have is that the lifted state is not refreshed per location - once I switch to a non-scrollable location, the CenterAlignedTopAppBar
remains lifted.
How can I fix this?
Note: I want to avoid creating a seperate TopAppBar per destination, as then the TopAppBar will also be affected from the navigation animations, which I don't want.