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

Jetpack Compose中Row使用animateContentSize时内容位置动画优化问题

Compose中Row容器动画时内部内容无法跟随中心位置动画的解决方法

用户提供的测试代码:

Row(
    modifier = Modifier
        .padding(horizontal = 16.dp)
        .padding(bottom = 16.dp)
        .align(Alignment.BottomEnd)
        .background(AppTheme.colors.tetriary, shape = AppTheme.shapes.medium)
        .animateContentSize(animationSpec = tween(durationMillis = 2000))
        .height(AppDimens.Size.size_48)
        .width(
            if (someBoolean) {
                256.dp
            } else {
                128.dp
            }
        ),
    horizontalArrangement = Arrangement.Center,
    verticalAlignment = Alignment.CenterVertically
) {
    Spacer(modifier = Modifier.size(24.dp)
        .background(color = AppTheme.colors.secondaryGreen))
    Spacer(modifier = Modifier.size(24.dp)
        .background(color = AppTheme.colors.redDark))
}

问题描述

上述代码中,animateContentSize可以让Row容器的背景边界正常执行动画,但内部的Spacer会在动画开始时直接跳转到最终位置,无法跟随Row的中心位置平滑移动。需要实现内部内容始终保持在Row中心并跟随容器尺寸动画平滑过渡。


解决思路

问题核心是animateContentSize仅处理容器尺寸的动画,但Row的宽度是通过if-else瞬间切换的,布局系统直接计算出内容的最终中心位置,跳过了过渡过程。正确做法是让Row的宽度本身平滑变化,让布局系统自动调整内部内容的位置,实现同步动画。

修改后的代码

使用animateDpAsState动画化Row的宽度,替代直接的条件赋值:

// 在Composable函数内定义动画化的宽度值
val rowWidth by animateDpAsState(
    targetValue = if (someBoolean) 256.dp else 128.dp,
    animationSpec = tween(durationMillis = 2000)
)

Row(
    modifier = Modifier
        .padding(horizontal = 16.dp)
        .padding(bottom = 16.dp)
        .align(Alignment.BottomEnd)
        .background(AppTheme.colors.tetriary, shape = AppTheme.shapes.medium)
        .height(AppDimens.Size.size_48)
        .width(rowWidth), // 使用动画化的宽度
    horizontalArrangement = Arrangement.Center,
    verticalAlignment = Alignment.CenterVertically
) {
    Spacer(modifier = Modifier.size(24.dp)
        .background(color = AppTheme.colors.secondaryGreen))
    Spacer(modifier = Modifier.size(24.dp)
        .background(color = AppTheme.colors.redDark))
}

原理说明

  • animateDpAsState会让Row的宽度在2000ms内平滑从128dp过渡到256dp(或反向),而非瞬间切换。
  • 随着Row宽度逐渐变化,Arrangement.Center会持续计算内容的中心位置,内部Spacer会跟随这个变化平滑移动,实现整体同步的动画效果。
  • 此时无需再使用animateContentSize,因为宽度本身已经是动画变化的,容器背景会自然跟随宽度过渡而变化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 20:38:12