Flutter学习之 AnimationController

544 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第27天,点击查看活动详情

本文主要介绍下动画类AnimationController的使用

动画是通过把人物的表情、动作、变化等分解后画成许多动作瞬间的画幅,再用摄影机连续拍摄成一系列画面,给视觉造成连续变化的图画。它的基本原理与电影、电视一样,都是视觉暂留原理。

医学证明人类具有“视觉暂留”的特性,人的眼睛看到一幅画或一个物体后,在0.34秒内不会消失。利用这一原理,在一幅画还没有消失前播放下一幅画,就会给人造成一种流畅的视觉变化效果。

我们在flutter中使用简单的动画效果放大

Scaffold(
  appBar: AppBar(title: const Text(''),),
  body:Center(
    child: ElevatedButton(
      onPressed: () {
        setState(() {
          _size = 200;
        });
      },
      child: Icon(Icons.add,size: _size,)

    ),
  ) ,
)

iShot_2022-08-26_22.16.10.gif

虽然是变大了,但并没有什么动画效果,比较突兀,想要使其一点点放大需要引入 AnimationController,它是动画控制器,控制动画的启动、停止,还可以获取动画的运行状态,AnimationController 通常在 initState 方法中初始化:

class _AnimationCorePageState extends State<AnimationCorePage> with SingleTickerProviderStateMixin {
  double _size = 100;
  late AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(vsync: this,duration: Duration(milliseconds: 500));
  }

这里有两个参数需要设置:

  • vsync:当创建 AnimationController 时,需要传递一个vsync参数,存在vsync时会防止屏幕外动画消耗不必要的资源,单个 AnimationController 的时候使用 SingleTickerProviderStateMixin,多个 AnimationController 使用 TickerProviderStateMixin
  • duration:表示动画执行的时间。
onPressed: () {
  _controller.forward();
}

点击的时候不直接修改size,而是执行动画_controller.forward()。我们对AnimationController添加监听,发生变化的时候改变size

_controller = AnimationController(vsync: this,duration: const Duration(milliseconds: 500));
 _controller.addListener(() {
setState(() {
_size = 100+100*_controller.value;
});
});

iShot_2022-08-26_22.27.50.gif

_controller.value 是当前动画的值,默认从 0 到 1。也可以通过参数形式设置最大值和最小值:

_controller = AnimationController(vsync: this,duration: const Duration(milliseconds: 500),lowerBound: 100,upperBound: 200);
 _controller.addListener(() {
setState(() {
_size = _controller.value;
});
});

动画的状态分为四种:

  • dismissed:动画停止在开始处。
  • forward:动画正在从开始处运行到结束处(正向运行)。
  • reverse:动画正在从结束处运行到开始处(反向运行)。
  • completed:动画停止在结束处。

动画的控制方法:

  • forward:正向执行动画。
  • reverse:反向执行动画。
  • repeat:反复执行动画。
  • reset:重置动画。

监听动画的状态

_controller.addStatusListener((status) {

  if(status == AnimationStatus.completed){
    _controller.reverse();
  }else if(status == AnimationStatus.dismissed){
    _controller.forward();
  }
});

只需监听动画状态变化,在动画结束后再正向/反向再次执行动画。

iShot_2022-08-26_22.34.43.gif