Flutter 学习笔记 11 - 动画一
2019-01-22 本文已影响0人
三流之路
Flutter 的动画基于 Animation,Widget 在 build 方法中读取 Animation 对象当前值,并可以监听动画的状态改变。
- Animation 是 Flutter 动画库的一个核心抽象类,要使用需要
import 'package:flutter/animation.dart';
- Animation 拥有其当前值和状态(完成或停止)。
- Animation 不知道在屏幕显示的内容,本身和 UI 渲染没有任何关系。
- Animation 对象是一个在一段时间内依次生成一个区间值的类,输出可以是线性函数、曲线函数、阶梯函数或者任何函数映射。
- 根据 Animation 对象的控制方式,动画可以反向运行,甚至可以在中间切换方向。
- Animation 对象有状态,通过
.value
获取动画的当前值。 - Animation 可以生成
Animation<double>
、Animation<Color>
或Animation<Size>
。
AnimationController
继承 Animation<double>
,生成 double 值。
在屏幕刷新的每一帧,AnimationController 都会生成一个新的值。默认情况下,AnimationController 在给定的时间段内会线性的生成从 0.0 到 1.0 的数字。必须通过调用 forward()
方法才能启动它运行。
final AnimationController controller = AnimationController(
duration: const Duration(milliseconds: 2000), vsync: this);
vsync 参数可以防止屏幕外动画消耗不必要的资源,即当显示动画的 widget 不在屏幕显示时,动画定时器会暂停,当再次显示时,会恢复执行。通过 mixin 特性将 SingleTickerProviderStateMixin 添加到类定义中。
通过 .value
获取动画当前值。
Animation 对象可以通过 addListener()
添加监听,当 value 值发生变化时,就会调用监听器。
import 'package:flutter/material.dart';
import 'package:flutter/animation.dart';
// 得用 StatefulWidget
class AnimScreen extends StatefulWidget {
@override
State<StatefulWidget> createState() => AnimState();
}
// 通过 mixin 引入 SingleTickerProviderStateMixin
class AnimState extends State<AnimScreen> with SingleTickerProviderStateMixin {
AnimationController controller;
// 在 initState 中初始化 controller
@override
initState() {
super.initState();
controller = AnimationController(
duration: const Duration(milliseconds: 2000), vsync: this)
..addListener(() {
setState(() {
// 修改状态,引起 build
});
});
controller.forward(); // 启动动画
}
Widget build(BuildContext context) {
return Center(
child: Container(
margin: EdgeInsets.symmetric(vertical: 10.0),
// 根据动画值修改尺寸,由于 contrller 的 value 从 0 到 1,所以乘以 300
height: 300 * controller.value,
width: 300 * controller.value,
child: FlutterLogo(),
),
);
}
dispose() {
controller.dispose();
super.dispose();
}
}
在 2000ms 内,AnimationController 的 value 从 0.0 到 1.0,则 Widget 的尺寸从 0 到 300。
动画完成时会执行 dispose 方法,在这里释放控制器以防止内存泄漏。
2019_01_10_18_46_41.gif