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

如何让Jetpack Compose中的该动画执行完成后停止而非无限循环?

解决方案:让Jetpack Compose动画执行完成后停止循环

原代码使用了rememberInfiniteTransition,这是Jetpack Compose专门用于无限循环动画的API,因此要实现动画执行完成后停止,需要替换为非无限的动画方案,以下是两种可行实现:


方案一:使用animateAsState(简单直接)

animateAsState默认只执行一次动画,完成后保持目标状态,适合不需要复杂控制的场景。

修改后完整代码

@Composable
fun Gojo(
    maxWidth: Dp,
    maxHeight: Dp,
) {
    val gojoSize = 200.dp
    
    // 替换无限循环动画为单次执行的animateAsState
    val positionState by animateAsState(
        targetValue = 1f,
        animationSpec = tween(
            durationMillis = 1000,
            easing = LinearEasing
        ),
        // 可选:动画完成后的回调操作
        finishedListener = { /* 比如更新状态、打印日志等 */ }
    )

    // 根据动画状态计算Modifier
    val modifier = when {
        positionState <= 0.1f -> Modifier.offset(
            x = -140.dp,
            y = maxHeight * 0.75f,
        ).rotate(50.0F)
        positionState <= 0.2f -> Modifier.offset(
            x = -100.dp,
            y = maxHeight * 0.75f,
        ).rotate(50.0F)
        positionState <= 0.25f -> Modifier.offset(
            x = -100.dp,
            y = maxHeight * 0.75f,
        ).rotate(0.0F)
        positionState <= 0.3f -> Modifier.offset(
            x = -100.dp + (maxWidth * positionState),
            y = maxHeight * 0.75f,
        ).rotate(50.0F)
        else -> Modifier.offset(
            x = maxWidth * 0.25f,
            y = maxHeight * 0.75f,
        )
    }

    val resource = painterResource(R.drawable.gojo)
    Image(
        modifier = modifier.width(gojoSize).height(gojoSize),
        painter = resource,
        contentDescription = "gojo sama"
    )
}

扩展:执行一次来回动画后停止

如果需要动画先从0f到1f,再反向回到0f后停止,修改animationSpec为:

animationSpec = repeatable(
    iterations = 2, // 执行2次动画:0→1,再1→0
    animation = tween(1000, LinearEasing),
    repeatMode = RepeatMode.Reverse
)

方案二:使用Animatable(灵活可控)

Animatable提供更细粒度的动画控制,支持手动启动、暂停、重置,适合需要复杂动画逻辑的场景。

修改后完整代码

@Composable
fun Gojo(
    maxWidth: Dp,
    maxHeight: Dp,
) {
    val gojoSize = 200.dp
    
    // 创建Animatable实例,初始值为0f
    val positionState = remember { Animatable(0f) }

    // 首次启动Composable时执行动画,仅执行一次
    LaunchedEffect(Unit) {
        // 执行从0f到1f的动画
        positionState.animateTo(
            targetValue = 1f,
            animationSpec = tween(1000, LinearEasing)
        )
        // 可选:取消注释可执行来回动画
        // positionState.animateTo(
        //     targetValue = 0f,
        //     animationSpec = tween(1000, LinearEasing)
        // )
    }

    // 根据动画状态计算Modifier
    val modifier = when {
        positionState.value <= 0.1f -> Modifier.offset(
            x = -140.dp,
            y = maxHeight * 0.75f,
        ).rotate(50.0F)
        positionState.value <= 0.2f -> Modifier.offset(
            x = -100.dp,
            y = maxHeight * 0.75f,
        ).rotate(50.0F)
        positionState.value <= 0.25f -> Modifier.offset(
            x = -100.dp,
            y = maxHeight * 0.75f,
        ).rotate(0.0F)
        positionState.value <= 0.3f -> Modifier.offset(
            x = -100.dp + (maxWidth * positionState.value),
            y = maxHeight * 0.75f,
        ).rotate(50.0F)
        else -> Modifier.offset(
            x = maxWidth * 0.25f,
            y = maxHeight * 0.75f,
        )
    }

    val resource = painterResource(R.drawable.gojo)
    Image(
        modifier = modifier.width(gojoSize).height(gojoSize),
        painter = resource,
        contentDescription = "gojo sama"
    )
}

核心修改说明

  1. 移除rememberInfiniteTransition:该API的设计目的就是无限循环,无法直接停止,必须替换为非无限动画实现。
  2. 选择合适的动画API:
    • animateAsState:适合简单的单次动画,代码简洁。
    • Animatable:适合需要手动控制动画生命周期的复杂场景。
  3. 调整动画规格:将infiniteRepeatable替换为tween(单次动画)或repeatable(指定次数的重复动画)。

内容的提问来源于stack exchange,提问作者Avinash Muralidharan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 05:15:28