在我的 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)。但关键帧似乎并不能做到这一点(无论如何,这样的测试可能不是最好的主意)。
您可以组合
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")
}