如何在运行时更新 LottieCompose clipSpec

How do I update a LottieCompose clipSpec at runtime

我有一个 Lottie 动画,我想开始然后当它到达某个帧时我想从第 X 帧循环到第 Y 帧。

我 运行 遇到的问题是我似乎无法弄清楚如何在运行时使用 LottieCompose 更新 clipSpec,因为 clipSpec 无法重新分配.

我可以用正常的 XML 基于 Lottie 的布局来做到这一点

loading_animation.addAnimatorUpdateListener {

    if(initialLoad && loading_animation.frame == 15){
        initialLoad = false
        startTime = System.currentTimeMillis()
        loading_animation.setMinAndMaxFrame(15,28)
    }

    if(!initialLoad && authenticated && System.currentTimeMillis() >= (startTime+1000)){
        loading_animation.pauseAnimation()
        startActivity()
    }

}

这是我的 LottieCompose 目前为止的代码

val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.sun_icon))
val animatable = rememberLottieAnimatable()
val progress by animateLottieCompositionAsState(composition, iterations = LottieConstants.IterateForever)
LottieAnimation(composition = composition, progress = progress, modifier = Modifier.wrapContentSize())

clipSpec 可以用 animateLottieCompositionAsState 指定。您可以像 Compose 中的任何其他状态一样更新它:创建一个状态变量并用一些 action/side-effect.

更新它

在 Compose documentation, including this youtube video 中详细了解状态,它解释了基本原则。

getFrameForProgress returns Float 中的一帧,我不确定将其转换为 Int 并比较相等是否安全(是否保证每个帧已渲染?在慢速设备上可能不会),所以我的比较代码看起来不太好。

val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw. sun_icon))
var clipSpec by remember { mutableStateOf<LottieClipSpec?>(null)}
val progress by animateLottieCompositionAsState(
    composition = composition,
    clipSpec = clipSpec,
    iterations = LottieConstants.IterateForever
)
LottieAnimation(
    composition = composition,
    progress = progress,
    modifier = Modifier.wrapContentSize()
)
var initialLoad by remember { mutableStateOf(true) }
if (initialLoad && composition?.getFrameForProgress(progress)?.let { it >= 15f } == true) {
    SideEffect {
        initialLoad = false
        clipSpec = LottieClipSpec.Frame(
            min = 15,
            max = 28
        )
    }
}