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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 20:02:27