Flutter常用动画
2020-12-24 本文已影响0人
刘铁崧
Animation类——抽象类
包含:
监听动画值的改变
监听动画状态的改变
value(获取当前值)
status(获取当前状态)
开发中我们通常使用子类AnimationController(继承自Animation)
-flutter中渲染时必须收到一个同步信号vsync,GPU才会进行下一步渲染
-使用AnimationController时要传入一个vsync,需要将当前widget传入,但是要混入SingleTickerProviderStateMixin类
(vsync的作用:程序退出后台后控制动画的绘制)
-forward(向前执行动画)
-reverse(动画反转)
CurvedAnimation类(设置动画执行的速率)(速度曲线)
官方文档:https://api.flutter.dev/flutter/animation/Curves-class.html
Tween类(设置动画执行的value范围)
begin(开始值)
end(结束值)
简单实用 —— 实现放大缩小动画(心跳效果)
效果:
流程:
初始化函数中穿件动画
设置动画效果CurvedAnimation
设置动画执行value(不设置默认为0.0 - 1.0范围)
addListener监听动画值的改变,并刷新(影响性能)
addStatusListener监听动画状态的改变(处理不同状态下的事件)
UI渲染中如果想用到动画设置的value,可以通过Animation对象下的value获取(_animation.value)
dispose析构函数中销毁动画控制器
class _TestNavigatorState extends State<TestNavigator> with SingleTickerProviderStateMixin{
AnimationController _animationController;
Animation _animation;
@override
void initState() {
// TODO: implement initState
super.initState();
// 创建动画
_animationController = AnimationController(
duration: Duration(seconds: 1),
vsync: this
);
// 设置Curve
_animation = CurvedAnimation(parent: _animationController, curve: Curves.easeInOut);
// 设置Tween
_animation = Tween(begin: 50.0,end: 100.0).animate(_animation);
// 监听动画值的改变
_animationController.addListener(() {
setState(() {
});
});
// 监听动画状态的改变
_animationController.addStatusListener((status) {
if(status == AnimationStatus.completed){// 动画执行完成
// 反转动画
_animationController.reverse();
}
else if(status == AnimationStatus.dismissed){// 动画状态恢复到初始状态
_animationController.forward();
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("动画"),
),
body: Center(
child:Column(
children: [
Icon(Icons.favorite,color: Colors.red,size: _animation.value),
FloatingActionButton(
child: Icon(Icons.play_arrow),
onPressed: (){
if (_animationController.isAnimating){// 动画正在执行
_animationController.stop();
}
else{// 动画执行结束
if (_animationController.status == AnimationStatus.forward){
// 动画正向执行
_animationController.forward();
}
else if (_animationController.status == AnimationStatus.reverse){
// 动画反转执行
_animationController.reverse();
}
else{
_animationController.forward();
}
}
// _animationController.isAnimating ? _animationController.stop() : _animationController.forward();
},
)
],
)
),
);
}
}
@override
void dispose() {
_animationController.dispose();
// TODO: implement dispose
super.dispose();
}
高性能动画优化方案
1. 使用AnimationWidget避免频繁build整个widget
缺点:每次都要创建一个类,并且如果有子类依然会重复build
class HeartAnimation extends AnimatedWidget {
HeartAnimation(Animation animation):super(listenable:animation);
@override
Widget build(BuildContext context) {
Animation animation = listenable;
return Icon(Icons.favorite,color: Colors.red,size: animation.value);
}
}
外部调用时直接使用HeartAnimation()并传入animation
body: Center(
child:Column(
children: [
HeartAnimation(_animation),
FloatingActionButton(
child: Icon(Icons.play_arrow),
onPressed: (){}
}
),
2.使用AnimatedBuilder(最高效便捷)
AnimatedBuilder(
animation: _animationController,
builder: (context,child){
return Icon(Icons.favorite,color: Colors.red,size: _animation.value);
},
),