如何在Jetpack Compose中实现AnimatedImageVector逐个路径点击动画
解决方案
1. 为每个圆形创建独立动画
在res/animator/目录下创建动画文件(比如animate_circle.xml,如果需要不同效果可创建animate_circle_1.xml到animate_circle_33.xml),定义你需要的动画效果(以旋转为例):
<!-- res/animator/animate_circle.xml --> <objectAnimator android:duration="500" android:propertyName="rotation" android:valueFrom="0" android:valueTo="360" android:valueType="floatType"/>
2. 更新Animated Vector配置
修改res/drawable/animated_vector.xml,为所有33个圆形Group添加target关联动画:
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/drawable"> <!-- 为每个circle添加target,重复到circle33 --> <target android:animation="@animator/animate_circle" android:name="circle1" /> <target android:animation="@animator/animate_circle" android:name="circle2" /> ... <target android:animation="@animator/animate_circle" android:name="circle33" /> </animated-vector>
3. Compose中实现逐个动画逻辑
放弃原有的atEnd全局状态,改用计数器跟踪当前动画的圆形索引,每次点击触发下一个圆的动画,完成后可重置:
@Composable fun CircleAnimation() { val context = LocalContext.current // 获取AnimatedVectorDrawableCompat实例,用于精准控制单个target动画 val avd = remember { AnimatedVectorDrawableCompat.create(context, R.drawable.animated_vector)!! } // 记录当前动画的圆形索引,0表示未开始,1-33对应各个圆形 var currentCircleIndex by remember { mutableStateOf(0) } // 用BitmapPainter实时刷新动画状态 val painter = remember { BitmapPainter(avd.toBitmap()) } // 索引变化时启动对应圆形的动画 LaunchedEffect(currentCircleIndex) { if (currentCircleIndex in 1..33) { avd.getTargetAnimator("circle$currentCircleIndex")?.apply { duration = 500 start() // 动画结束后更新Bitmap,刷新UI addListener(object : Animator.AnimatorListener { override fun onAnimationEnd(animation: Animator?) { painter.bitmap = avd.toBitmap() } override fun onAnimationStart(animation: Animator?) {} override fun onAnimationCancel(animation: Animator?) {} override fun onAnimationRepeat(animation: Animator?) {} }) } } } Image( painter = painter, contentDescription = "逐个动画的圆形", modifier = Modifier .fillMaxWidth() .height(400.dp) .clickable { if (currentCircleIndex < 33) { // 点击触发下一个圆的动画 currentCircleIndex++ } else { // 所有圆动画完成后重置状态 avd.reset() painter.bitmap = avd.toBitmap() currentCircleIndex = 0 } }, contentScale = ContentScale.Fit ) }
核心说明
- 使用
AnimatedVectorDrawableCompat可以单独控制每个圆形Group的动画,摆脱全局atEnd状态的限制。 - 计数器
currentCircleIndex负责跟踪当前动画进度,点击时递增,直到所有33个圆完成后重置。 - 动画结束后更新
BitmapPainter的bitmap,确保Compose能实时刷新UI显示最新动画状态。
内容的提问来源于stack exchange,提问作者Mohamed ALI
相关产品推荐
相关产品推荐

