Flutter 学习之旅(三十四) Flutter 动画(一)
Flutter 中的动画由 Animation、Curve、Controller、Tween共同组成,每一个组件都有他们特定的职责,
下面我们一个一个介绍
AnimationController
AnimationController({
double value,
///动画过渡时间
this.duration,
this.reverseDuration,
this.debugLabel,
///动画开始的值
this.lowerBound = 0.0,
///动画结束的值
this.upperBound = 1.0,
this.animationBehavior = AnimationBehavior.normal,
///用来改变过程中的value的
@required TickerProvider vsync,
})
AnimationController用于控制动画,它包含动画的正向执行forward()、停止stop() 、反向播放 reverse()等方法。他的区间是(0~1) 不可以超过这个区间 ,并在预定时间内将这个数据不断的由一端过度到另一端,每一帧都会生成一个新的值,这个过度的速度是由Curve 来控制的, 屏幕每一次刷新都是一帧,每一帧都会调用 TickerProvider来刷新当前的动画的过渡值,并利用这个过渡值来构建当前的动画状态
AnimationController 可以使用addListener 可以获取动画过渡的值,addStatusListener 可以监听状态发生改变,
如果想要重复执行一个正向动画 forward(),
_controller
..value=0
..forward();
注意这里如果想要每次都执行这个动画,必须重置这个value,这个问题困扰了我很久,
并且在widget 的dispose 的方法内取消注册
@override
void dispose() {
animatedContainer.dispose();
super.dispose();
}
TickerProvider 用来改变过程中的value的,使用的方法是 混入到需要的widget 中,通常为 SingleTickerProviderStateMixin,具体的作用原理还不是很理解,这里只能后来再完善了
Animation
Animation 是一个抽象类,他保存了动画的插值和状态,他在一定时间内依次生成Tween之间的值,获取的这个值可以是均匀的,也可是先快后慢等 ,这是由Curve决定的 ;动画不仅正向运行,也可以反向运行,一些比较常用的Animation 类比如Animation <double> ,Animation <Size>,Animation <Color>,Animation <Offset>等,这里我们需要记住一个比较重要的知识点,那就是Animation 存了动画的插值和状态,我们可以按照动画正向即从0~1开始执行,如果我们想要获取 0.5的时候的值,则使用Tween.transform 则可以获得,这是一个非常重要的点.
Curve
Curve是用来控制动画执行的速度的,flutter 中就是利用Curve来控制这个速度,并把匀速的线性动画称为
Curves.linear ,将AnimationController利用CurvedAnimation 进行包装,
例子
animatedContainer = AnimationController(
duration: Duration(seconds: 2),
lowerBound: 0,
upperBound: 1,
vsync: this);
///改变起始值
Animation curve =
CurvedAnimation(parent: animatedContainer, curve: Curves.easeIn,);
Tween
默认情况下AnimationController的数据是否0-1执行的,但是我们需要将它放大到0-100怎么执行呢,这里使用
Tween 改变起始值就可以了,并使用tween.animate()来获取动画对象
例子
_tween=IntTween(begin: 0, end: 255)
anim=_tween.animate(_tween);
同样可以封装ColorTween
tween=ColorTween(begin: widget.begin,end: widget.end) ;
anim=tween.animate(CurvedAnimation(parent: _controller,curve: Curves.easeOut));
下面写一个简单的例子
这个例子是控制文本的颜色Color.fromARGB(animation.value, 1, 1, 1),只需要从0-255 之间就可以了
然后先正向执行,再反向执行无限重复这个动画,
class _TsmAnimationState extends State<TsmAnimationPage>
with SingleTickerProviderStateMixin {
Animation<int> animation;
AnimationController animatedContainer;
@override
void initState() {
animatedContainer = AnimationController(
duration: Duration(seconds: 2),
lowerBound: 0,
upperBound: 1,
vsync: this);
///添加变速模型
Animation curve =
CurvedAnimation(parent: animatedContainer, curve: Curves.easeIn,);
///改变起始值
animation = IntTween(begin: 0, end: 255).animate(curve);
animatedContainer.addListener(() {
setState(() {
printString("value:${animation.value}");
});
});
animatedContainer.addStatusListener((status) {
if(status==AnimationStatus.completed){
animatedContainer.reverse();
}else if(status==AnimationStatus.dismissed){
animatedContainer.forward();
}
});
animatedContainer.forward();
super.initState();
}
@override
void dispose() {
animatedContainer.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Animation 学习"),
centerTitle: true,
),
body: Container(
child: Center(
child: Text(
"重复渐隐动画",
style: TextStyle(
color: Color.fromARGB(animation.value, 1, 1, 1),
),
),
),
),
);
}
}
效果图
GIF 2020-9-15 9-33-51.gif
我学习flutter的整个过程都记录在里面了
https://www.jianshu.com/c/36554cb4c804
最后附上demo 地址