Jetpack Compose:无法为Scaffold底部栏高度添加动画效果
问题解决:Scaffold底部栏显示/隐藏时内容内边距无动画
你的问题核心是Scaffold无法感知AnimatedVisibility的高度动画变化,导致contentPadding的调整是瞬间完成的,和底部栏的滑动动画不同步。
解决方案:用AnimatedContent替代AnimatedVisibility
AnimatedContent会在状态切换时带动画地更新组件尺寸,Scaffold能自动感知这个尺寸变化,进而让contentPadding跟着产生动画效果,实现内容和底部栏的同步动画。
修改后的完整代码:
val lazyListState = rememberLazyListState() val isFloatingButtonVisible by derivedStateOf { lazyListState.firstVisibleItemIndex >= 2 } Scaffold( bottomBar = { AnimatedContent( targetState = isFloatingButtonVisible, transitionSpec = { // 保留原有滑动动画逻辑 slideInVertically { height -> height } with slideOutVertically { height -> height } } ) { visible -> if (visible) { Row( modifier = Modifier.padding(8.dp), horizontalArrangement = Arrangement.spacedBy(8.dp) ) { repeat(2) { Button( modifier = Modifier .height(48.dp) .weight(1f), onClick = {} ) { Text(text = "Something") } } } } else { // 隐藏时返回高度为0的占位,避免布局跳动 Spacer(modifier = Modifier.height(0.dp)) } } } ) { contentPadding -> LazyColumn( modifier = Modifier.padding(contentPadding), state = lazyListState, contentPadding = PaddingValues(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp) ) { item { Text( text = LoremIpsum(50).values.joinToString(" ") ) } item { Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { repeat(2) { Button(onClick = {}) { Text(text = "Bla Bla") } } } } item { Text( text = LoremIpsum(700).values.joinToString(" ") ) } } }
原理说明
- AnimatedContent在状态切换时,会对新旧内容的尺寸变化添加动画过渡,Scaffold的contentPadding会基于底部栏的实时高度动态调整,自然就带上了动画效果。
- 保留了你原有的滑动动画逻辑,同时保证Snackbar和内容始终位于悬浮按钮上方(Scaffold的bottomBar层级低于Snackbar,符合需求)。
内容的提问来源于stack exchange,提问作者daniyelp
相关产品推荐
相关产品推荐

