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

如何重启Flutter的TweenAnimation?按钮/文本变更时重启动画

解决方案

1. 解决LateInitializationError与vsync参数问题

要使用AnimationController,你需要:

  • 让你的State类混入SingleTickerProviderStateMixin(单动画控制器场景),当前State实例就能作为vsync参数的提供者,避免动画在后台无效消耗资源。
  • 在initState方法中主动初始化AnimationController,不能仅用late修饰却不完成初始化。

2. 实现文本变更/按钮点击时重启模糊动画

  • 按钮点击:直接调用动画控制器的reset() + forward()方法重启动画。
  • 文本变更:通过didUpdateWidget对比新旧widget的文本值,或者用ValueListenableBuilder监听文本变量,一旦变化就触发动画重启。

完整代码示例

import 'dart:ui';
import 'package:flutter/material.dart';

class BlurTextAnimation extends StatefulWidget {
  final String customText;

  const BlurTextAnimation({super.key, required this.customText});

  @override
  State<BlurTextAnimation> createState() => _BlurTextAnimationState();
}

// 混入SingleTickerProviderStateMixin提供vsync支持
class _BlurTextAnimationState extends State<BlurTextAnimation> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _blurAnimation;

  @override
  void initState() {
    super.initState();
    // 初始化动画控制器,vsync传入当前State实例
    _controller = AnimationController(
      duration: const Duration(milliseconds: 1500),
      vsync: this,
    );
    // 创建模糊度动画:从0到5再回到0
    _blurAnimation = Tween<double>(begin: 0, end: 5).animate(
      CurvedAnimation(parent: _controller, curve: Curves.easeInOut),
    )..addStatusListener((status) {
        if (status == AnimationStatus.completed) {
          _controller.reverse();
        }
      });
    // 初始执行一次动画
    _controller.forward();
  }

  // 监听文本变更,自动重启动画
  @override
  void didUpdateWidget(covariant BlurTextAnimation oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.customText != widget.customText) {
      _restartAnimation();
    }
  }

  // 封装重启动画的方法,按钮点击直接调用
  void _restartAnimation() {
    _controller.reset();
    _controller.forward();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        // 用AnimatedBuilder构建模糊文本
        AnimatedBuilder(
          animation: _blurAnimation,
          builder: (context, child) {
            return BackdropFilter(
              filter: ImageFilter.blur(
                sigmaX: _blurAnimation.value,
                sigmaY: _blurAnimation.value,
              ),
              child: child,
            );
          },
          child: Text(
            widget.customText,
            style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
          ),
        ),
        const SizedBox(height: 20),
        ElevatedButton(
          onPressed: _restartAnimation,
          child: const Text('重新执行动画'),
        ),
      ],
    );
  }
}

// 使用示例
void main() {
  runApp(const MaterialApp(home: HomePage()));
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  String _text = '初始文本';

  void _changeText() {
    setState(() {
      _text = '文本已变更 ${DateTime.now().second}';
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('文本模糊动画')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            BlurTextAnimation(customText: _text),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: _changeText,
              child: const Text('修改文本'),
            ),
          ],
        ),
      ),
    );
  }
}

代码说明

  • SingleTickerProviderStateMixin:为AnimationController提供vsync,确保动画仅在组件可见时运行。
  • didUpdateWidget:对比新旧文本值,文本变更时自动重启动画。
  • _restartAnimation:封装重置并启动动画的逻辑,按钮点击和文本变更场景可复用。
  • BackdropFilter:配合AnimatedBuilder实现文本模糊效果的动态更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 13:03:13