JetPack Compose:点击按钮重置动画并切换图标的实现问询
实现点击切换图标并重置边框动画的方案
关键改动思路
- 新增状态管理当前显示的图标,点击按钮时循环切换图标
- 用一个触发计数器控制动画重置,每次点击让计数器递增,触发动画重新执行
- 动画执行前先强制重置到初始值,再从头播放收缩效果
完整代码示例
@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
相关产品推荐
相关产品推荐

