Flutter动画系统详解

一、动画系统核心概念

1. 动画类型

  • 隐式动画 :通过 AnimatedFoo 组件自动处理动画

  • 显式动画 :通过 AnimationController 手动控制动画

2. 核心类

Dart 复制代码
// 主要动画类
Animation<T>        // 动画值容器
AnimationController // 动画控制器
Tween<T>           // 定义动画值范围
Curve             // 定义动画曲线

二、隐式动画(最简单)

示例:基本隐式动画组件

Dart 复制代码
// AnimatedContainer - 自动动画化属性变化
AnimatedContainer(
  duration: Duration(seconds: 1),
  width: _selected ? 200.0 : 100.0,
  height: _selected ? 200.0 : 100.0,
  color: _selected ? Colors.red : Colors.blue,
)

// AnimatedOpacity - 透明度动画
AnimatedOpacity(
  opacity: _visible ? 1.0 : 0.0,
  duration: Duration(milliseconds: 500),
)

// AnimatedSwitcher - 子组件切换动画
AnimatedSwitcher(
  duration: Duration(milliseconds: 500),
  child: _showFirst 
    ? Text("First", key: ValueKey(1))
    : Text("Second", key: ValueKey(2)),
)

三、显式动画(更灵活)

1. 基本显式动画流程

Dart 复制代码
class MyAnimation extends StatefulWidget {
  @override
  _MyAnimationState createState() => _MyAnimationState();
}

class _MyAnimationState extends State<MyAnimation> 
    with SingleTickerProviderStateMixin {
  
  AnimationController _controller;
  Animation<double> _animation;
  
  @override
  void initState() {
    super.initState();
    
    // 1. 创建动画控制器
    _controller = AnimationController(
      duration: Duration(seconds: 2),
      vsync: this,  // 需要混入 SingleTickerProviderStateMixin
    );
    
    // 2. 创建动画曲线
    final curve = CurvedAnimation(
      parent: _controller,
      curve: Curves.easeInOut,
    );
    
    // 3. 创建 Tween 和动画
    _animation = Tween<double>(
      begin: 0.0,
      end: 300.0,
    ).animate(curve);
    
    // 4. 添加状态监听
    _controller.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        _controller.reverse();
      } else if (status == AnimationStatus.dismissed) {
        _controller.forward();
      }
    });
  }
  
  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _animation,
      builder: (context, child) {
        return Container(
          width: _animation.value,
          height: _animation.value,
          color: Colors.blue,
        );
      },
    );
  }
  
  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}

2. 使用 AnimationController 方法

Dart 复制代码
// 启动动画
_controller.forward();    // 正向播放
_controller.reverse();    //反向播放
_controller.reset();      // 重置
_controller.stop();       // 停止
_controller.repeat();     // 重复播放

// 控制动画
_controller.animateTo(0.5); // 动画到特定值

四、常用动画组件

1. Hero 动画(页面切换动画)

Dart 复制代码
// 页面 A
Hero(
  tag: 'image-hero',
  child: Image.asset('images/flutter.png'),
  flightShuttleBuilder: (flightContext, animation, direction, fromContext, toContext) {
    return ScaleTransition(
      scale: animation.drive(Tween(begin: 0.0, end: 1.0)),
      child: toContext.widget,
    );
  },
)

// 页面 B(使用相同 tag)
Hero(
  tag: 'image-hero',
  child: Image.asset('images/flutter.png'),
)

2. 交错动画 (Staggered Animation)

Dart 复制代码
// 创建多个动画序列
_controller = AnimationController(
  duration: Duration(milliseconds: 2000),
  vsync: this,
);

// 定义多个动画
_widthAnimation = Tween<double>(
  begin: 50,
  end: 200,
).animate(CurvedAnimation(
  parent: _controller,
  curve: Interval(0.0, 0.5), // 在 0-50% 的时间段执行
));

_heightAnimation = Tween<double>(
  begin: 50,
  end: 200,
).animate(CurvedAnimation(
  parent: _controller,
  curve: Interval(0.5, 1.0), // 在 50-100% 的时间段执行
));
相关推荐
程序员Ctrl喵18 小时前
异步编程:Event Loop 与 Isolate 的深层博弈
开发语言·flutter
前端不太难20 小时前
Flutter 如何设计可长期维护的模块边界?
flutter
小蜜蜂嗡嗡21 小时前
flutter列表中实现置顶动画
flutter
始持21 小时前
第十二讲 风格与主题统一
前端·flutter
始持21 小时前
第十一讲 界面导航与路由管理
flutter·vibecoding
始持21 小时前
第十三讲 异步操作与异步构建
前端·flutter
新镜1 天前
【Flutter】 视频视频源横向、竖向问题
flutter
黄林晴1 天前
Compose Multiplatform 1.10 发布:统一 Preview、Navigation 3、Hot Reload 三箭齐发
android·flutter
Swift社区1 天前
Flutter 应该按功能拆,还是按技术层拆?
flutter
肠胃炎1 天前
树形选择器组件封装
前端·flutter