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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 19:28:20