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

ObjectAnimator的repeatCount与repeatMode属性在AnimatedVector中不生效

问题原因

你的问题并非ObjectAnimator存在适配问题,不需要切换到传统Animation实现。核心原因是Jetpack Compose的animatedVectorResourceAPI本身的设计限制:该API专为单次双向状态切换动画设计,只会响应atEnd的状态变更播放一次过渡动画,会直接忽略XML中定义的repeatCount、repeatMode循环属性,因此才会出现动画仅执行一次就停止的情况。

解决方案

方案1:保留现有XML动画定义,使用原生AnimatedVectorDrawable控制

无需修改你已经编写的scale.xml、矢量图和动画矢量配置,直接在Compose中通过AndroidView包裹原生ImageView加载动画即可,XML中设置的循环属性会正常生效:

var avd: AnimatedVectorDrawable? = null
AndroidView(
    factory = { context ->
        ImageView(context).apply {
            setImageResource(R.drawable.my_animated_vector)
            avd = drawable as AnimatedVectorDrawable
            avd?.start()
        }
    },
    modifier = Modifier
        .size(maxWidth / (7 / 2), maxHeight / (15 / 2))
        .constrainAs(moon) {
            top.linkTo(stars.bottom)
            start.linkTo(squizzelle.start, maxWidth / 13)
        }
)
// 页面销毁时停止动画避免内存泄漏
DisposableEffect(Unit) {
    onDispose {
        avd?.stop()
    }
}

方案2:改用Compose原生无限动画API实现(更推荐)

完全抛弃XML动画定义,使用Compose自带的无限动画API实现效果,性能更好,也更符合Compose的开发范式:

// 定义无限循环缩放动画
val infiniteTransition = rememberInfiniteTransition(label = "moon_scale_anim")
val scale by infiniteTransition.animateFloat(
    initialValue = 1f,
    targetValue = 1.5f,
    animationSpec = infiniteRepeatable(
        animation = tween(
            durationMillis = 1000,
            easing = BounceEasing
        ),
        repeatMode = RepeatMode.Reverse
    ),
    label = "moon_scale_value"
)

Image(
    painter = painterResource(id = R.drawable.ic_moon),
    contentDescription = "Moon",
    contentScale = ContentScale.Fit,
    modifier = Modifier
        .size(maxWidth / (7 / 2), maxHeight / (15 / 2))
        // 应用缩放动画
        .graphicsLayer {
            scaleX = scale
            scaleY = scale
        }
        .constrainAs(moon) {
            top.linkTo(stars.bottom)
            start.linkTo(squizzelle.start, maxWidth / 13)
        }
)
注意事项

你当前矢量图中所有陨石坑的group都使用了相同的crater名称,AnimatedVectorDrawable绑定动画时默认只会作用到第一个匹配name的group。如果需要所有陨石坑都同步执行缩放,可以把所有crater group放到同一个父group中,给父group设置唯一名称,再把动画绑定到该父group即可。

内容的提问来源于stack exchange,提问作者Loïc Jackotin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 17:24:03