Flutter 旋转动画 — RotationTransition

系列文章

  1. Flutter 旋转动画 — RotationTransition
  2. Flutter 平移动画 — 4种实现方式
  3. Flutter 淡入淡出与逐渐出现动画
  4. Flutter 尺寸缩放、形状、颜色、阴影变换动画
  5. Flutter 列表Item动画 — AnimatedList实现Item左进左出、淡入淡出
  6. Flutter Hero 实现共享元素转场动画
  7. Flutter Hero 实现径向变换动画 — 圆形变成矩形的转场动画
  8. Flutter 自定义动画 — 数字递增动画和文字逐行逐字出现或消失动画


1 旋转动画效果对比

旋转动画

2 动画基础知识

  • Animation 是 Flutter 动画库中的核心类,它插入用于引导动画的值。
  • AnimationController 管理动画。例如控制动画开始、停止、前进、后退等。
  • CurvedAnimation 将进程定义为非线性曲线。
  • Tween 在被动画对象使用的数据范围之间进行插值。 例如,Tween 可以定义从红色到蓝色或从 0 到 255 的插值。
  • Listeners 和 StatusListeners 可监控动画状态的变化。
  • AnimatedWidget 是展示动画的Widget,Flutter提供一些动画Widget让我们快速实现动画效果。例如:
    AnimatedBuilder、 AnimatedModalBarrier、DecoratedBoxTransition、FadeTransition、PositionedTransition、RelativePositionedTransition、RotationTransition、ScaleTransition、SizeTransition、SlideTransition

3 旋转动画案例

RotationTransition 继承于AnimatedWidget,是一个提供旋转功能的Widget,需要传入参数 Animation<double>。

Animation<double>中的值为 v,则旋转的弧度是 v * 2 * π

3.1 线性变化的旋转动画(补间动画 Tween)

3.1.1 首先创建 Animation 与 AnimationController

  /// 会重复播放的控制器
  late final AnimationController _repeatController;

  /// 线性动画
  late final Animation<double> _animation;

  @override
  void initState() {
    
    
    super.initState();
    /// 动画持续时间是 3秒,此处的this指 TickerProviderStateMixin
    _repeatController = AnimationController(
      duration: const Duration(seconds: 3),
      vsync: this,
    )
      ..repeat(); // 设置动画重复播放

    // 创建一个从0到360弧度的补间动画 v * 2 * π
    _animation = Tween<double>(begin: 0, end: 1).animate(_repeatController);
  }

3.1.2 构建Widget RotationTransition

  @override
  Widget build(BuildContext context) {
    
    
    return Scaffold(
      body: Center(
        child: RotationTransition(
          turns: _animation,
          child: const Icon(Icons.arrow_drop_up, size: 180),
        ),
      ),
    );
  }

3.1.3 效果图

在这里插入图片描述


3.2 非线性变化的旋转动画(Curved­Animation)

3.2.1 代码实现

实现方式与线性变化的旋转动画类似,只是需要将 Tween 更改为 Curved­Animation

  class _RotationTransitionPageState extends State<RotationTransitionPage>
    with TickerProviderStateMixin {
    
    
  /// 会重复播放的控制器
  late final AnimationController _repeatController;

  /// 非线性动画
  late final Animation<double> _curveAnimation;

  @override
  void initState() {
    
    
    super.initState();
    _repeatController = AnimationController(
      duration: const Duration(seconds: 3),
      vsync: this,
    )..repeat();

    /// Curves 存在多种模式,具体的效果查看Curves源码,有链接展示动画效果
    _curveAnimation = CurvedAnimation(
      parent: _repeatController,
      curve: Curves.easeInCirc,
    );
  }

  @override
  Widget build(BuildContext context) {
    
    
    return Scaffold(
      body: Center(
        child: RotationTransition(
          turns: _curveAnimation,
          child: const Icon(Icons.arrow_drop_up, size: 180),
        ),
      ),
    );
  }
}

3.2.2 效果图

在这里插入图片描述


3.3 动画延时重复(每次重复播放前停顿一下)

实现思路:监听动画的状态,每当动画播放完成时延时一段时间,然后启动动画开始播放。

3.3.1 代码实现

 class _RotationTransitionPageState extends State<RotationTransitionPage>
    with TickerProviderStateMixin {
    
    
  /// 重复播放前需要停顿一下的控制器
  late final AnimationController _delayRepeatController;

  /// 延时重复播放动画
  late final Animation<double> _delayAnimation;

  @override
  void initState() {
    
    
    super.initState();
    _delayRepeatController = AnimationController(
      duration: const Duration(seconds: 3),
      vsync: this,
    )
    //  添加动画监听
      ..addListener(() {
    
    
        // 获取动画当前的状态
        var status = _delayRepeatController.status;
        if (status == AnimationStatus.completed) {
    
    
          // 延时1秒
          Future.delayed(const Duration(seconds: 1), () {
    
    
            //从0开始向前播放
            _delayRepeatController.forward(from: 0.0);
          });
        }
      })
      ..forward();

    _delayAnimation =
        Tween<double>(begin: 0, end: 1).animate(_delayRepeatController);
  }

  @override
  Widget build(BuildContext context) {
    
    
    return Scaffold(
      body: Center(
        child: RotationTransition(
          turns: _delayAnimation,
          child: const Icon(Icons.arrow_drop_up, size: 180),
        ),
      ),
    );
  }
}

3.3.2 效果图

在这里插入图片描述


3.4 手动控制旋转动画

实现方式:使用 AnimationController 的 animateTo 函数。

3.4.1 代码实现

class _RotationTransitionPageState extends State<RotationTransitionPage>
    with TickerProviderStateMixin {
    
    
  /// 手动控制动画的控制器
  late final AnimationController _manualController;

  /// 手动控制
  late final Animation<double> _manualAnimation;

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

    /// 不设置重复,使用代码控制进度,动画时间1秒
    _manualController = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 1),
    );
    _manualAnimation =
        Tween<double>(begin: 0, end: 1).animate(_manualController);
  }

  @override
  Widget build(BuildContext context) {
    
    
    return Scaffold(
      body: Center(
        child: RotationTransition(
          turns: _manualAnimation,
          child: CupertinoButton(
            onPressed: () {
    
    
              /// 获取动画当前的值
              var value = _manualController.value;

              /// 0.5代表 180弧度
              if (value == 0.5) {
    
    
                _manualController.animateTo(0);
              } else {
    
    
                _manualController.animateTo(0.5);
              }
            },
            child: const Icon(Icons.arrow_drop_up, size: 180),
          ),
        ),
      ),
    );
  }
}

3.4.2 效果图

在这里插入图片描述

4 注意

别忘了释放AnimationController 资源。

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

猜你喜欢

转载自blog.csdn.net/ww897532167/article/details/125280054