Flutter:如何检测调用stop()后的AnimationController状态
Flutter AnimationController stop() 后状态异常问题
我遇到了一个问题:调用stop()方法后检测动画状态时,状态仍然是AnimationStatus.forward,示例代码如下:
if (timerControllerList[index].isAnimating) { await timerControllerList[index].stop(); } if (timerControllerList[index].status == AnimationStatus.forward) { // 代码竟然会走到这里 :( }
我有2个计时器动画(用List存储控制器),支持在10秒结束前独立暂停。需求是:当暂停其中任意一个时,检测另一个是否也已停止,但目前所有控制器的状态都显示为forward。
初始化代码如下:
void initTimer(int index) { // 从initState()中调用 late AnimationController timerController; late Animation<int> timerAnimation; int timerCounter = 10; timerController = AnimationController( vsync: this, duration: Duration(seconds: timerCounter), ); timerAnimation = StepTween(begin: 0, end: timerCounter * 1000).animate(timerController) ..addStatusListener((status) { if (status == AnimationStatus.completed) { stopTimer(index); } }); timerControllerList.add(timerController); timerAnimationList.add(timerAnimation); }
问题原因
AnimationController.stop()仅暂停动画的执行流程,不会修改动画的status属性——调用后状态会保持在暂停前的状态(此处即为forward),这就是你判断状态时出现异常的原因。
解决方案
1. 直接用isAnimating判断停止状态
stop()调用后,isAnimating会立即变为false,可以直接用这个属性替代status判断动画是否停止:
if (timerControllerList[index].isAnimating) { await timerControllerList[index].stop(); } // 检测动画是否已停止 if (!timerControllerList[index].isAnimating) { // 执行暂停后的逻辑 }
2. 维护自定义状态标记
如果需要区分“主动暂停”和“自然结束”的状态,可以额外维护一个状态列表:
// 在State类中定义 List<bool> _isTimerPaused = []; // 初始化计时器时同步添加状态 void initTimer(int index) { // ... 原有初始化代码 ... timerControllerList.add(timerController); timerAnimationList.add(timerAnimation); _isTimerPaused.add(false); } // 暂停计时器时更新标记 Future<void> pauseTimer(int index) async { if (timerControllerList[index].isAnimating) { await timerControllerList[index].stop(); _isTimerPaused[index] = true; } } // 检测所有计时器是否都已停止 bool areAllTimersStopped() { return _isTimerPaused.every((paused) => paused) && timerControllerList.every((controller) => !controller.isAnimating); }
3. 调用reset()重置状态(可选)
如果需要让status变为AnimationStatus.dismissed,可以在stop()后调用reset(),但这会将动画重置到初始值:
if (timerControllerList[index].isAnimating) { await timerControllerList[index].stop(); timerControllerList[index].reset(); // 重置后status变为dismissed } if (timerControllerList[index].status == AnimationStatus.dismissed) { // 此时可以进入该分支 }
内容的提问来源于stack exchange,提问作者Dani
相关产品推荐
相关产品推荐

