Open aurimas-zarskis opened 2 years ago
Can you provide a minimal code snippet to help me reproduce your issue?
I am using AnimatedNavHost from accompanist with no animation when switching between destinations. Regular NavHost with fade animation actually hides text size change, but adding breakpoint to text size calculation you can see that progress is dispatched multiple times without scroll
@OptIn(ExperimentalAnimationApi::class)
@Composable
private fun Test() {
val navController = rememberNavController()
Column(modifier = Modifier.fillMaxSize()) {
NavHost(
navController = navController,
startDestination = "first",
modifier = Modifier.fillMaxSize().weight(1f)
) {
composable("first"
) { FirstScreen() }
composable("second") { SecondScreen() }
}
BottomNav(navController = navController)
}
}
@Composable
private fun BottomNav(navController: NavHostController) {
BottomNavigation() {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
BottomNavigationItem(
icon = { Icon(Icons.Default.Home, contentDescription = null) },
label = { Text("First") },
selected = currentDestination?.hierarchy?.any { it.route == "first" } == true,
onClick = {
navController.navigate("first") {
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
}
)
BottomNavigationItem(
icon = { Icon(Icons.Default.Home, contentDescription = null) },
label = { Text("Second") },
selected = currentDestination?.hierarchy?.any { it.route == "second" } == true,
onClick = {
navController.navigate("second") {
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
}
)
}
}
@Composable
private fun FirstScreen() {
val state = rememberCollapsingToolbarScaffoldState()
CollapsingToolbarScaffold(
modifier = Modifier
.fillMaxSize(),
state = state,
scrollStrategy = ScrollStrategy.ExitUntilCollapsed,
toolbar = {
val textSize = remember(state.toolbarState.progress) {
(22 + (34 - 22) * state.toolbarState.progress).sp
}
Box(
modifier = Modifier
.background(Color.Gray)
.fillMaxWidth()
.height(120.dp)
.pin()
)
Text(
text = "First",
fontSize = textSize,
modifier = Modifier
.road(Alignment.CenterStart, Alignment.BottomStart)
.padding(
start = 16.dp,
end = 16.dp,
top = 18.dp,
bottom = 18.dp
),
)
}
) {
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
) {
Text(text = "First screen")
}
}
}
@Composable
private fun SecondScreen() {
val state = rememberCollapsingToolbarScaffoldState()
CollapsingToolbarScaffold(
modifier = Modifier
.fillMaxSize(),
state = state,
scrollStrategy = ScrollStrategy.ExitUntilCollapsed,
toolbar = {
val textSize = remember(state.toolbarState.progress) {
(22 + (34 - 22) * state.toolbarState.progress).sp
}
Box(
modifier = Modifier
.background(Color.Gray)
.fillMaxWidth()
.height(120.dp)
.pin()
)
Text(
text = "Second",
fontSize = textSize,
modifier = Modifier
.road(Alignment.CenterStart, Alignment.BottomStart)
.padding(
start = 16.dp,
end = 16.dp,
top = 18.dp,
bottom = 18.dp
),
)
}
) {
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
) {
Text(text = "Second screen")
}
}
}
I can confirm the issue, also seeing this when navigating back from a detail screen to a screen with expanded toolbar and there the title flickers (first is small and then big), because its font size depends on progress.
Could narrow it down to the height being the initial value (maximum int value) and thus progress being near 0 (because height is in the denominator for calculating progress).
@onebone any update on this?
I can confirm the issue and looks like its cause is about timing as @ChristopherKlammt said. As a workaround, I added minHeight
, maxHeight
to the rememerSaveable
and it stopped being dispatched twice. It might be relevant to the fact that the composition at the very first time doesn't dispatch textSize
change twice?
@onebone can you share the code for that?
Edit: I looked into it and created a PR for that change, is that how you did it as well?
CollapsingToolbarScaffoldState.toolbarState.progress
value changes when you go back in navigation stack even though no scrolling is happening. If toolbar title size depends on progress value, it visibly changes from smallest to largest when navigating back to screen. It seems that when navigating back, two progress values are dispatched, 0.0f and then 1.0f.