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

如何在Material3 1.4.0-alpha16中用animatedWidth实现ButtonGroup宽度动画?

解决Material3 ButtonGroup按钮宽度动画问题(1.4.0-alpha16版本)

问题背景

Google IO 2025推出的新ButtonGroup Composable,其非废弃重载的子项lambda未提供普通@Composable作用域,直接在其中调用带动画逻辑的按钮组件会触发报错:Composable invocations may only happen from the context of a @Composable function,同时无法直接使用animatedWidth Modifier实现点击宽度变化效果。

核心解决方案

将带动画的按钮逻辑封装为独立的@Composable组件,通过外部状态驱动,在ButtonGroup的add方法中引用该组件(add的content参数支持@UiComposable调用已定义的Composable函数)。

具体实现代码

1. 封装带宽度动画的按钮组件

@Composable
fun AnimatedToggleButton(
    isSelected: Boolean,
    onClick: () -> Unit,
    text: String
) {
    // 定义宽度动画状态
    val animatedWidth by animateDpAsState(
        targetValue = if (isSelected) 120.dp else 60.dp,
        animationSpec = spring(stiffness = Spring.StiffnessMediumLow)
    )

    Button(
        onClick = onClick,
        modifier = Modifier.width(animatedWidth),
        colors = ButtonDefaults.buttonColors(
            containerColor = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.surfaceVariant
        )
    ) {
        Text(text = text)
    }
}

2. 在ButtonGroup中集成动画按钮

@Composable
fun ButtonGroupWithAnimatedButtons() {
    // 维护选中状态
    var selectedIndex by remember { mutableIntStateOf(0) }
    val buttonTexts = listOf("选项1", "选项2", "选项3")

    ButtonGroup(
        modifier = Modifier
            .safeDrawingPadding()
            .padding(horizontal = 4.dp)
            .fillMaxWidth(),
        overflowIndicator = {}
    ) {
        buttonTexts.forEachIndexed { index, text ->
            add(
                content = {
                    // 调用封装好的动画按钮,传入状态
                    AnimatedToggleButton(
                        isSelected = selectedIndex == index,
                        onClick = { selectedIndex = index },
                        text = text
                    )
                }
            )
        }
    }
}

关键说明

  • 动画逻辑完全封装在独立的Composable组件内,避免在ButtonGroup的非Composable作用域中直接编写动画代码。
  • 通过外部的选中状态驱动按钮宽度变化,确保动画状态的管理符合Composable的状态规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 19:18:21