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

JetPack Compose:点击按钮重置动画并切换图标的实现问询

实现点击切换图标并重置边框动画的方案

关键改动思路

  1. 新增状态管理当前显示的图标,点击按钮时循环切换图标
  2. 用一个触发计数器控制动画重置,每次点击让计数器递增,触发动画重新执行
  3. 动画执行前先强制重置到初始值,再从头播放收缩效果

完整代码示例

@Composable
fun IconCardDemo() {
    // 定义要切换的图标列表
    val iconList = listOf(
        Icons.Default.DoneAll,
        Icons.Default.Close,
        Icons.Default.Check,
        Icons.Default.Star
    )
    // 管理当前图标索引
    var currentIconIndex by remember { mutableStateOf(0) }
    // 动画触发计数器,每次点击递增来重置动画
    var animationTrigger by remember { mutableStateOf(0) }

    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center,
        modifier = Modifier.fillMaxSize()
    ) {
        // 带动画边框的卡片组件
        CardWithAnimatedBorder(
            currentIcon = iconList[currentIconIndex],
            iconColor = Color.White,
            animationTrigger = animationTrigger
        )

        // 切换按钮
        Button(
            onClick = {
                // 循环切换图标
                currentIconIndex = (currentIconIndex + 1) % iconList.size
                // 触发动画重置
                animationTrigger += 1
            },
            modifier = Modifier.padding(top = 20.dp)
        ) {
            Text("切换图标")
        }
    }
}

@Composable
fun CardWithAnimatedBorder(
    currentIcon: ImageVector,
    iconColor: Color,
    animationTrigger: Int
) {
    val animateShape = remember { Animatable(50f) }

    Card(
        modifier = Modifier
            .size(100.dp)
            .padding(5.dp)
            .border(width = Dp(animateShape.value), Color.White, shape = CircleShape),
        shape = CircleShape,
        elevation = 5.dp,
        backgroundColor = Color.BlueGrey,
    ) {
        Icon(
            imageVector = currentIcon,
            contentDescription = "切换图标",
            tint = iconColor,
            modifier = Modifier.padding(12.dp)
        )
    }

    LaunchedEffect(animationTrigger) {
        // 先立刻重置动画到初始的50dp宽度
        animateShape.snapTo(50f)
        // 再执行收缩动画到2dp
        animateShape.animateTo(
            targetValue = 2f,
            animationSpec = repeatable(
                animation = tween(
                    durationMillis = 3000,
                    easing = LinearEasing,
                    delayMillis = 500
                ),
                iterations = 1
            )
        )
    }
}

核心逻辑说明

  • 图标切换:通过currentIconIndex循环遍历图标列表,每次点击按钮更新索引实现图标切换
  • 动画重置:用animationTrigger作为LaunchedEffect的依赖,每次点击让计数器加一,强制LaunchedEffect重新执行;执行动画前调用snapTo(50f)直接把边框宽度重置到初始值,再从头播放收缩动画
  • 解耦组件:把卡片和动画逻辑封装成独立的CardWithAnimatedBorder组件,通过参数传递状态,提升复用性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 22:35:23