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

Jetpack Compose:无需硬编码值实现wrapContentSize与fillMaxSize动画切换

实现Compose组件在wrapContentSize与fillMaxSize间的双向动画切换

问题分析

你当前的代码存在两个核心问题:

  1. 将Modifier存储为mutableState是冗余且错误的——Compose中Modifier应根据状态动态生成,而非保存为状态变量。
  2. animateContentSize主要用于内容自身变化时的尺寸动画,而你需要的是容器主动在wrapContentSize和fillMaxSize之间切换,该API无法直接满足这种场景。

解决方案

使用BoxWithConstraints获取父容器的可用尺寸,结合animateSizeAsState实现两种状态间的平滑过渡,无需硬编码任何数值:

@Composable
fun ExpandableBox() {
    var expanded by remember { mutableStateOf(false) }
    // 记录初始wrap状态下的组件尺寸
    var wrapSize by remember { mutableStateOf(Size.Zero) }

    BoxWithConstraints(modifier = Modifier.fillMaxSize()) {
        // 根据展开状态确定目标尺寸
        val targetSize = if (expanded) {
            Size(maxWidth.toPx(), maxHeight.toPx())
        } else {
            wrapSize
        }

        // 尺寸动画
        val animatedSize by animateSizeAsState(
            targetValue = targetSize,
            animationSpec = tween(3000, easing = LinearEasing),
            label = "expandAnimation"
        )

        Box(
            modifier = Modifier
                // 应用动画后的尺寸
                .size(animatedSize.width.dp, animatedSize.height.dp)
                .background(Color.Green)
                .clickable { expanded = !expanded }
                // 首次渲染时记录wrap状态的尺寸
                .onSizeChanged { size ->
                    if (!expanded && wrapSize == Size.Zero) {
                        wrapSize = Size(size.width.toFloat(), size.height.toFloat())
                    }
                },
            contentAlignment = Alignment.Center
        ) {
            Text(text = "Testing....")
        }
    }
}

代码说明

  • BoxWithConstraints:提供父容器的maxWidth和maxHeight,作为fillMaxSize状态的目标尺寸。
  • wrapSize:通过onSizeChanged在组件首次以wrapContentSize渲染时记录其真实尺寸,作为收起状态的目标尺寸。
  • animateSizeAsState:负责在wrapSize和父容器尺寸之间执行平滑的尺寸过渡动画。
  • 点击事件直接切换expanded状态,触发动画更新。

内容的提问来源于stack exchange,提问作者It's me guys

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 01:44:57