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

如何重置无控制器的TweenAnimationBuilder动画?Flutter开发问题

如何重置无控制器的TweenAnimationBuilder动画

TweenAnimationBuilder没有内置的AnimationController,要重启它的核心是让组件重新触发初始化,以下是两种实用方案:

方案1:通过Key强制重建组件

定义一个状态变量作为TweenAnimationBuilder的key,每次需要重启时更新这个key并调用setState,Flutter会销毁旧组件并创建新实例,动画将从头开始执行。

修改后的代码示例:

int _countdownKey = 0;
bool countingDown = true;

// 重启倒计时的方法
void _restartCountdown() {
  setState(() {
    countingDown = true;
    // 更新key,触发组件重建
    _countdownKey++;
  });
}

@override
Widget build(BuildContext context) {
  return TweenAnimationBuilder<Duration>(
    key: ValueKey(_countdownKey), // 添加唯一key
    duration: const Duration(seconds: 4),
    tween: Tween(
        begin: const Duration(seconds: 4), end: const Duration(seconds: 1)),
    onEnd: () {
      setState(() {
        countingDown = false;
      });
    },
    builder: (BuildContext context, Duration value, Widget? child) {
      final seconds = value.inSeconds % 60;

      return Text(
        '$seconds',
        style: const TextStyle(fontSize: 100),
      );
    },
  );
}

方案2:通过状态变量切换触发重建

先将动画状态设为结束,等待一帧后再重新开启,触发动画从头执行:

修改后的代码示例:

bool countingDown = true;

// 重启倒计时的方法
void _restartCountdown() {
  setState(() {
    countingDown = false;
  });
  // 等待下一帧确保组件更新后,再重新开启动画
  WidgetsBinding.instance.addPostFrameCallback((_) {
    setState(() {
      countingDown = true;
    });
  });
}

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: Center(
      child: countingDown 
          ? TweenAnimationBuilder<Duration>(
              duration: const Duration(seconds: 4),
              tween: Tween(
                  begin: const Duration(seconds: 4), end: const Duration(seconds: 1)),
              onEnd: () {
                setState(() {
                  countingDown = false;
                });
              },
              builder: (BuildContext context, Duration value, Widget? child) {
                final seconds = value.inSeconds % 60;
                return Text(
                  '$seconds',
                  style: const TextStyle(fontSize: 100),
                );
              },
            )
          : const Text('1', style: TextStyle(fontSize: 100)),
    ),
    floatingActionButton: FloatingActionButton(
      onPressed: _restartCountdown,
      child: const Icon(Icons.refresh),
    ),
  );
}

两种方案对比:

  • 方案1更直接,无论动画执行到哪个阶段,都能立即重启,适合大多数场景。
  • 方案2不需要修改组件key,通过状态切换实现,适合需要保持组件树结构的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 07:50:11