You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 17:40:38