flutter3.0学习笔记

Animation

Preview
  • Animation
  • 源码
  • addListener
  • addStatusListener
  • AnimationStatus
  • 实现图片逐渐放大效果

Animation

Animation是一个抽象类,是动画核心类,而它主要的功能是保存动画的插值和状态;其中一个比较常用的Animation类是Animation<double>Animation对象是一个在一段时间内依次生成一个区间(Tween)之间值的类。Animation对象在整个动画执行过程中输出的值可以是线性的、曲线的、一个步进函数或者任何其他曲线函数等等,这由Curve来决定。 根据Animation对象的控制方式,动画可以正向运行(从起始状态开始,到终止状态结束),也可以反向运行,甚至可以在中间切换方向。Animation还可以生成除double之外的其他类型值,如:Animation<Color> Animation<Size>。在动画的每一帧中,我们可以通过Animation对象的value属性获取动画的当前状态值。

源码

abstract class Animation<T> extends Listenable implements ValueListenable<T> {
  const Animation();
  // 添加动画监听器
  @override
  void addListener(VoidCallback listener);
  // 移除动画监听器
  @override
  void removeListener(VoidCallback listener);
  // 添加动画状态监听器
  void addStatusListener(AnimationStatusListener listener);
  // 移除动画状态监听器
  void removeStatusListener(AnimationStatusListener listener);
  // 获取动画当前状态
  AnimationStatus get status;
  // 获取动画当前的值
  @override
  T get value;

addListener

它可以用于给Animation添加帧监听器,在每一帧都会被调用。帧监听器中最常见的行为是改变状态后调用setState()来触发UI重建。

调用方法:

animation.addListener(() => setState((){}));

addStatusListener

它可以给Animation添加“动画状态改变”监听器;动画开始、结束、正向或反向(见AnimationStatus定义)时会调用状态改变的监听器。

调用方法:

animation.addStatusListener((status) {});

AnimationStatus

AnimationStatus是一个枚举类,主要保存动画的4种状态,分别是动画停止状态、从头到尾执行中状态、从尾到头执行中状态、动画执行完状态。

enum AnimationStatus {
  /// 动画停止状态
  dismissed,
  /// 从头到尾执行中状态
  forward,
  /// `从尾到头执行中状态
  reverse,
  /// 动画执行完状态
  completed,
}

实现图片逐渐放大效果

import 'package:flutter/material.dart';

class ScaleAnimationPage extends StatefulWidget {
  const ScaleAnimationPage({Key? key}) : super(key: key);

  @override
  State<ScaleAnimationPage> createState() => _ScaleAnimationPageState();
}

class _ScaleAnimationPageState extends State<ScaleAnimationPage> with SingleTickerProviderStateMixin {

  late AnimationController _controller;
  late Animation<double> _animation;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    //创建动画控制器
    _controller = AnimationController(
        duration: const Duration(seconds: 2),
        vsync: this
    );
    //使用Tween图片宽高从0变到300
    _animation = Tween(begin: 0.0,end: 300.0).animate(_controller);
    //监听动画,并且更新ui
    _controller.addListener(() {
      setState(() {
       //监听插值变化
       print(_animation.value);
      });
    });
    _controller.addStatusListener((status) {
      print(status);
      //AnimationStatus.forward(动画正在正向执行)
      //AnimationStatus.completed( 动画在终点停止)
      //AnimationStatus.dismissed(动画在起始点停止)
      //AnimationStatus.reverse(动画正在反向执行)

    });
    //启动动画正向执行
    _controller.forward();
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    _controller.dispose();//路由销毁时需要释放动画资源,以防止内存泄漏
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('图片变大'),),
      body: Center(
        child: Image.asset('images/avatar.jpg',width: _animation.value,height: _animation.value,),
      ),
    );
  }
}

效果:

ani1 (1).gif