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

Flutter中调用setState为何会意外重启Timer动画?

问题:Timer动画调用setState后自动重启及animate_do流行度疑问

1. 问题现象

我实现了一个可正常运行的Timer动画,从0计数到10,显示格式为整数:三位小数(例如2:453)。当Timer结束或停止后,会显示一个重新开始按钮,目前按钮的点击事件仅包含空的setState调用:

setState(() {
});

但调用这个setState后,Timer会自动继续运行,就像执行了timerControllerList[index].forward()一样。我尝试给显示时间的Text组件添加唯一Key,但没有效果。

2. 相关代码实现

Timer组件代码

Widget timer(int index) {
    return Center(
      child: AnimatedBuilder(
        animation: timerAnimationList[index],
        builder: (context, child) {
          final double seconds = timerAnimationList[index].value / 1000;
          final int integer = seconds.truncate();
          final int decimals = (seconds % 1 * 1000).truncate();
          String decimalsString = decimals.toString();

          switch (decimalsString.length) {
            case 1:
              decimalsString = '00$decimals';
            case 2:
              decimalsString = '0$decimals';
          }

          return Text(
            '${integer.toString()}:$decimalsString',
            style: const TextStyle(fontSize: 50),
          );
        },
      ),
    );
}

状态类与Timer初始化代码

class _GamePageState extends State<GamePage> with TickerProviderStateMixin {
  List<dynamic> timerControllerList = [];
  List<Animation> timerAnimationList = [];

  @override
  void initState() {
    super.initState();
    initTimer();
  } 

  void initTimer() {
      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) {
                print('TIMER FINISHED');
              }
            });

      timerControllerList.add(timerController);
      timerAnimationList.add(timerAnimation);
  }
}

组件层级

Stack(
  children: [
    timer(),
    button(),
  ],
)

重新开始按钮代码(使用animate_do)

SlideInUp(
  manualTrigger: true,
  delay: const Duration(seconds: 2),
  controller: (controller) => playAgainButtonController = controller,
  child: ElevatedButton...
)

3. 额外信息

  • 测试环境中,使用普通无动画按钮时,仅调用setState不会出现此问题,只有用animate_do的SlideInUp包裹按钮后才会触发Timer自动重启。
  • Timer停止后,我通过playAgainButtonController.forward()来显示按钮。

疑问

  1. 为什么调用空的setState会导致已经停止的Timer动画自动继续运行?
  2. 上周安装animate_do时,它的流行度是98%,现在降到了76%,这是什么原因?

内容的提问来源于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 18:33:15