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

如何避免AnimatedVisibility状态变化时内容出现「跳跃」现象?

解决AnimatedVisibility切换时Text组件跳跃的问题

核心原因

AnimatedVisibility仅处理自身按钮的滑入滑出动画,但Row容器的布局尺寸变化是瞬间完成的,导致右侧Text组件直接跳转,无法跟随按钮的动画节奏平滑移动。要解决这个问题,需要让Row的布局尺寸变化也参与动画,保证按钮和Text的动效同步。

具体实现方案

方案1:给Row添加animateContentSize修饰符

这是最简洁的实现方式,通过让Row的尺寸变化伴随过渡动画,带动Text组件平滑移动:

Row(
    verticalAlignment = CenterVertically,
    modifier = Modifier
        .align(CenterVertically)
        .animateContentSize( // 新增:让Row尺寸变化平滑过渡
            animationSpec = tween(durationMillis = 300) // 可自定义动画时长、曲线
        )
) {
    AnimatedVisibility(
        visible = buttonBackEnabled,
        enter = slideInHorizontally(initialOffsetX = { -it }),
        exit = slideOutHorizontally(targetOffsetX = { -it })
    ) {
        ButtonBack(
            paddingValues = PaddingValues(0.dp, 0.dp, 5.dp, 0.dp),
            iconSize = 33.dp
        ) {
            mContext.findActivity()?.onBackPressed()
        }
    }
    Text(
        text = screenTitle,
        fontSize = 19.sp,
        fontWeight = FontWeight.SemiBold,
        modifier = Modifier
            .align(CenterVertically)
    )
}

方案2:用AnimatedContent单独控制Text动画

如果需要更精准地控制Text的移动曲线,可以将Text包裹在AnimatedContent中,根据按钮的显隐状态定义独立动画:

Row(
    verticalAlignment = CenterVertically,
    modifier = Modifier
        .align(CenterVertically)
) {
    AnimatedVisibility(
        visible = buttonBackEnabled,
        enter = slideInHorizontally(initialOffsetX = { -it }),
        exit = slideOutHorizontally(targetOffsetX = { -it })
    ) {
        ButtonBack(
            paddingValues = PaddingValues(0.dp, 0.dp, 5.dp, 0.dp),
            iconSize = 33.dp
        ) {
            mContext.findActivity()?.onBackPressed()
        }
    }
    AnimatedContent(
        targetState = buttonBackEnabled,
        transitionSpec = {
            // 按钮显示时Text向右移,隐藏时向左移,和按钮动画同步
            slideInHorizontally(initialOffsetX = { if (targetState) it else 0 }) with
            slideOutHorizontally(targetOffsetX = { if (targetState) 0 else -it }) using
            SizeTransform(clip = false)
        }
    ) { _ ->
        Text(
            text = screenTitle,
            fontSize = 19.sp,
            fontWeight = FontWeight.SemiBold,
            modifier = Modifier
                .align(CenterVertically)
        )
    }
}

优化提示

  • 建议统一按钮和布局动画的时长(比如都设为300ms),避免动效不同步
  • 可以给ButtonBack添加固定宽度修饰符(如.width(40.dp)),让动画的起始/结束位置更稳定
  • animateContentSize默认使用FastOutSlowInEasing曲线,若需要弹性效果可替换为spring()动画

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 13:00:46