Android 撰写动画 - 带重复侦听器的无限动画

问题描述 投票:0回答:1

在我的 android compose 项目中,我有一个这样的动画:

val infiniteTransition = rememberInfiniteTransition(label = "")

val x by infiniteTransition.animateFloat(
        initialValue = 0.5f, 
        targetValue = 0.0f, 
        animationSpec = infiniteRepeatable(
            animation = keyframes {
                durationMillis = cycleTime
                0.5f at 0 with xEasingOut
                1.0f at cycleTime / 4 with xEasingBack
                0.5f at cycleTime / 2 with xEasingOut
                0.0f at cycleTime * 3/4 with xEasingBack
                0.5f at cycleTime with xEasingOut
            },
            repeatMode = RepeatMode.Restart,
        ), 
        label = "x animation"
    )

效果很好。

但现在我想在每次动画重新启动时触发一些动作。对于像

animateFloatAsState
这样的简单动画,onCompleteListener 有一个 lambda,如

val x: Float by animateFloatAsState(
    targetValue = xTarget,
    animationSpec = tween(durationMillis = xDuration, easing = xEasing),
    label = "x animation",
) {
    // onCompleteListener lambda
}

但是我找不到类似的 lambda 来实现InfiniteTransition...

有没有办法做到这一点,或者最好的替代方法是什么?

Ps:起初我假设关键帧动画规范将确保 x 确实达到了相应的值 - 这就是我开始使用关键帧的原因(我假设我可以测试例如 x == 0)。但关键帧似乎并不能做到这一点(无论如何,这样的测试可能不是最好的主意)。

android android-jetpack-compose android-animation
1个回答
0
投票

您可以组合

LaunchedEffect
和变量来跟踪动画周期。以下是实现它的方法:

var restartCount by remember { mutableStateOf(0) }

val infiniteTransition = rememberInfiniteTransition(label = "")

val x by infiniteTransition.animateFloat(
        initialValue = 0.5f, 
        targetValue = 0.0f, 
        animationSpec = infiniteRepeatable(
            animation = keyframes {
                durationMillis = cycleTime
                0.5f at 0 with xEasingOut
                1.0f at cycleTime / 4 with xEasingBack
                0.5f at cycleTime / 2 with xEasingOut
                0.0f at cycleTime * 3/4 with xEasingBack
                0.5f at cycleTime with xEasingOut
            },
            repeatMode = RepeatMode.Restart,
        ), 
        label = "x animation"
    )
// Use LaunchedEffect to detect animation restart
    LaunchedEffect(x) {
        restartCount++
        // You can perform your action here whenever the animation restarts
        // You can also use restartCount to keep track of the number of restarts.
        println("Animation restarted. Restart count: $restartCount")
    }
© www.soinside.com 2019 - 2024. All rights reserved.