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

如何修复AnimatedVisibility中进入动画未完成时的退出动画异常?

解决Jetpack Compose中AnimatedVisibility中途切换动画的不平滑问题

问题核心是:当AnimatedVisibility的进入动画未完成时触发退出,内置的expandIn/shrinkOut组合动画无法衔接当前的中间状态,导致退出动画从最终尺寸快速执行。要实现平滑过渡,需要手动控制动画属性,让退出动画从当前状态插值到目标状态。

解决方案:手动管理动画状态

放弃依赖AnimatedVisibility的enter/exit参数,改用animate*AsState或updateTransition直接控制视图的透明度、尺寸等属性,状态切换时动画会自动从当前值平滑过渡。

代码示例:

val animationDuration = 1000 // 按需调整动画时长
val isVisible = remember { mutableStateOf(true) }

// 控制透明度动画
val alpha by animateFloatAsState(
    targetValue = if (isVisible.value) 1f else 0f,
    animationSpec = tween(durationMillis = animationDuration)
)

// 控制缩放,模拟expandIn/shrinkOut的展开/收缩效果
val scale by animateFloatAsState(
    targetValue = if (isVisible.value) 1f else 0f,
    animationSpec = tween(durationMillis = animationDuration)
)

// 若需从特定方向展开(如顶部),可替换为尺寸或偏移动画
// val height by animateDpAsState(
//     targetValue = if (isVisible.value) 200.dp else 0.dp,
//     animationSpec = tween(durationMillis = animationDuration)
// )

Box(
    modifier = Modifier
        .alpha(alpha)
        .scale(scale)
        // 若使用高度动画,替换为.height(height)
        .background(Color.Gray)
        .padding(16.dp)
) {
    Column {
        Text("动画视图内容")
        Button(
            onClick = { isVisible.value = false }
        ) {
            Text("关闭")
        }
    }
}

原理说明

  • 手动控制的动画属性(如alpha、scale)会持续跟踪当前值,切换isVisible状态时,动画系统自动计算从当前值到新目标值的插值,确保过渡平滑。
  • 若需模拟expandIn的方向展开效果,可替换scale为offset或size动画,根据需求调整目标值。

保留keyframes动画的方案

如果需要保留keyframes的帧动画效果,可在animationSpec中使用keyframes,过渡时会自动从当前帧继续:

val scale by animateFloatAsState(
    targetValue = if (isVisible.value) 1f else 0f,
    animationSpec = keyframes {
        durationMillis = animationDuration
        0f at 0
        0.5f at 300
        1f at animationDuration
    }
)

内容的提问来源于stack exchange,提问作者Mehmed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 08:50:58