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

Compose中AnimatedVisibility基于类型判断的退出动画问题及方案咨询

解决Compose AnimatedVisibility退出无动画问题

问题根源

你的初始代码中,当currentValue不再是MyType时,AnimatedVisibility内部的if (currentValue is MyType)判断直接不渲染MyComposable,导致退出动画没有可执行动画的内容,自然看不到退出效果。而currentComposer.cache是内部禁止使用的API,不能作为长期方案。

可行解决方案

方案1:用remember缓存最近的MyType实例

利用remember缓存值,仅在currentValue为MyType时更新缓存,确保退出动画期间仍能获取到之前的MyType实例:

AnimatedVisibility(visible = currentValue is MyType) {
    val cachedMyType = remember { mutableStateOf<MyType?>(null) }

    // 仅当currentValue是MyType时更新缓存,退出动画期间保留旧值
    if (currentValue is MyType) {
        cachedMyType.value = currentValue
    }

    cachedMyType.value?.let { myType ->
        MyComposable(myType = myType)
    }
}

方案2:结合MutableTransitionState精确控制缓存生命周期

如果需要在动画完全结束后清理缓存(避免内存占用),可以使用MutableTransitionState监听过渡状态:

val transitionState = remember {
    MutableTransitionState(false).apply {
        targetState = currentValue is MyType
    }
}

val cachedMyType = remember { mutableStateOf<MyType?>(null) }

// 更新缓存:仅当currentValue是MyType时
LaunchedEffect(currentValue) {
    if (currentValue is MyType) {
        cachedMyType.value = currentValue
    }
}

// 动画完全结束后清除缓存
LaunchedEffect(transitionState.isIdle) {
    if (!transitionState.targetState && transitionState.isIdle) {
        cachedMyType.value = null
    }
}

AnimatedVisibility(
    visibleState = transitionState,
    enter = fadeIn(), // 可替换为你需要的进入动画
    exit = fadeOut()  // 可替换为你需要的退出动画
) {
    cachedMyType.value?.let { myType ->
        MyComposable(myType = myType)
    }
}

为什么SideEffect会有延迟?

你之前尝试的SideEffect会延迟一帧,是因为SideEffect是在重组完成后才执行的,而我们需要在重组期间就更新缓存,这样AnimatedVisibility的内容才能及时拿到正确的值,避免动画出现空白或延迟。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 18:34:01