如何使 Jetpack Compose Image 动画无限

How to make Jetpack Compose Image animating infinite

我有一个 animated-vector 可绘制对象。 我希望此动画矢量在显示此图像时循环播放。 找不到好的解决方案。

        val image = animatedVectorResource(R.drawable.no_devices_animated)
        var atEnd by remember { mutableStateOf(false) }
        Image(
            painter = image.painterFor(atEnd),
            "image",
            Modifier.width(150.dp).clickable {
                atEnd = !atEnd
            },
            contentScale = ContentScale.Fit)

当我点击图片时,它正在播放动画,但随后停止了。这是一种无限的进步。

在这里留下我的解决方案(使用 compose 1.2.0-alpha07)。

在你的build.gradle

中添加依赖项
dependencies {
    implementation "androidx.compose.animation:animation:$compose_version"
    implementation "androidx.compose.animation:animation-graphics:$compose_version"
}

并执行以下操作:

@ExperimentalAnimationGraphicsApi
@Composable
fun AnimatedVectorDrawableAnim() {
    val image = AnimatedImageVector.animatedVectorResource(R.drawable.avd_anim)
    var atEnd by remember { mutableStateOf(false) }
    // This state is necessary to control start/stop animation
    var isRunning by remember { mutableStateOf(true) }
    // The coroutine scope is necessary to launch the coroutine 
    // in response to the click event
    val scope = rememberCoroutineScope()
    // This function is called when the component is first launched
    // and lately when the button is pressed
    suspend fun runAnimation() {
        while (isRunning) {
            delay(1000) // set here your delay between animations
            atEnd = !atEnd
        }
    }
    // This is necessary just if you want to run the animation when the
    // component is displayed. Otherwise, you can remove it.
    LaunchedEffect(image) {
        runAnimation()
    }
    Image(
        painter = rememberAnimatedVectorPainter(image, atEnd),
        null,
        Modifier
            .size(150.dp)
            .clickable {
                isRunning = !isRunning // start/stop animation
                if (isRunning) // run the animation if isRunning is true.
                    scope.launch {
                        runAnimation()
                    }
            },
        contentScale = ContentScale.Fit,
        colorFilter = ColorFilter.tint(Color.Red)
    )
}

如果您需要从头开始重复动画,我找到的唯一方法是使用动画矢量可绘制对象中声明的信息创建两个矢量可绘制对象,例如 ic_startic_end,然后执行以下:

// this is the vector resource of the start point of the animation
val painter = rememberVectorPainter(
    image = ImageVector.vectorResource(R.drawable.ic_start)
)
val animatedPainter = rememberAnimatedVectorPainter(
    animatedImageVector = AnimatedImageVector.animatedVectorResource(R.drawable.avd_anim),
    atEnd = !atEnd
)

Image(
    painter = if (atEnd) painter else animatedPainter,
    ...
)

所以,当动画矢量在结束位置时,绘制静态图像。延迟后,再次播放动画。如果您需要连续重复,请将延迟设置为与动画持续时间相同。

结果如下:

根据https://developer.android.com/jetpack/compose/resources#animated-vector-drawables

val image = AnimatedImageVector.animatedVectorResource(R.drawable.animated_vector)
val atEnd by remember { mutableStateOf(false) }
Icon(
    painter = rememberAnimatedVectorPainter(image, atEnd),
    contentDescription = null
)

要使动画无限循环:

val image = AnimatedImageVector.animatedVectorResource(id = vectorResId)
var atEnd by remember { mutableStateOf(false) }
Image(
    painter = rememberAnimatedVectorPainter(animatedImageVector = image, atEnd = atEnd),
    contentDescription = null,
)
LaunchedEffect(Unit) {
    while (true) {
        delay(animDuration)
        atEnd = !atEnd
    }
}