Jetpack Compose中animateColorAsState的finishedListener未调用问题
问题根源
- 你将
animateColorAsState放在了if (flashing)的条件分支内,当动画执行完成触发finishedListener时,回调中修改shouldFlash = false触发重组,此时if (flashing)条件不成立,动画所在代码块直接被移出Composition树,动画实例被销毁,绑定的finishedListener自然不会被执行。 - 现有动画逻辑不符合需求:你需要实现闪红后恢复透明的效果,需要让动画目标值随
flashing状态动态切换,而非仅在flashing为true时才创建动画实例。
修复方案
首先调整动画逻辑,将animateColorAsState提到条件分支外,根据flashing状态动态切换目标色,仅当动画恢复到透明状态时触发完成回调:
@Composable fun FlashingText(flashing: Boolean, text: String, flashFinished: () -> Unit) { val flashColor by animateColorAsState( targetValue = if (flashing) Color.Red else Color.Transparent, finishedListener = { endColor -> // 仅当动画结束在透明态时,代表整个闪红流程完成 if (endColor == Color.Transparent) { flashFinished() } } ) Text( text = text, // 根据背景色适配文字颜色,可按需求调整 color = if (flashColor == Color.Red) Color.White else Color.Black, modifier = Modifier.background(flashColor) ) }
如果需要实现变红后短暂停留再自动恢复透明的效果,无需手动控制shouldFlash的重置时机,改用Animatable实现序列动画更灵活:
@Composable fun FlashingText(flashing: Boolean, text: String, flashFinished: () -> Unit) { val flashColor = remember { Animatable(Color.Transparent) } // 监听flashing状态变化,触发闪红流程 LaunchedEffect(flashing) { if (flashing) { // 第一步:渐变到红色 flashColor.animateTo(Color.Red) // 第二步:停留100ms,可按需调整时长 delay(100) // 第三步:渐变恢复透明 flashColor.animateTo(Color.Transparent) // 整个动画完成后触发回调 flashFinished() } } Text( text = text, color = if (flashColor.value == Color.Red) Color.White else Color.Black, modifier = Modifier.background(flashColor.value) ) }
两种实现均兼容你使用的Compose 1.0.5及以上版本。
内容的提问来源于stack exchange,提问作者Alex Suzuki
相关产品推荐
相关产品推荐

