Implicit Animations
隐式动画:通常以Animated为开头的(AnimatedIcon,AnimatedBuilder是显式动画)数据变化时会自动进行动画,不用循环播放、不用随时中断、不用多个动画协同,它实现的是一种状态到另一种状态的改变
Explicit Animations
显示动画:以Transition结尾的,需要自己控制动画过程
以RotationTransition为例
默认_controller 是从0.0——1.0,可以通过 lowerbound 和 upperBound 来修改 AnimationController 生成数字的区间。也可以构建UI时候利用Tween来修改范围,如代码中注释部分_controller.drive(Tween(begin: 1, end: 2)),
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
//单个动画加with SingleTickerProviderStateMixin,多个动画加with TickerProviderStateMixin
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this, //程序的刷新频率与手机的频率统一
//Vsync 机制可以理解为是显卡与显示器的通信桥梁,显卡在渲染每一帧之前会等待垂
// 直同步信号,只有显示器完成了一次刷新时,发出垂直同步信号,显卡才会渲染下一帧,确保刷新率和帧率保
// 持同步,以达到供需平衡的效果,防止卡顿现象。
duration: const Duration(seconds: 5), //程序的执行时间
lowerBound: 3,
upperBound: 5
);
_controller.addListener((){
print("_controller值为${_controller.value}")
})
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Title'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
RotationTransition(
turns: _controller, //调用
//turns: _controller.drive(Tween(begin: 1, end: 2))
child: const FlutterLogo( //Logo
size: 150,
),
),
const SizedBox(
height: 40,
),
Padding(
padding: const EdgeInsets.fromLTRB(10, 0, 0, 0),
child: Wrap(
spacing: 10,
alignment: WrapAlignment.center,
children: [
ElevatedButton(
onPressed: () {
_controller.forward(); //正序播放一次
},
child: const Text("Forward")),
ElevatedButton(
onPressed: () {
_controller.reverse(); //倒序播放一次
},
child: const Text("Reverse")),
ElevatedButton(
onPressed: () {
_controller.stop(); //停止播放
},
child: const Text("Stop")),
ElevatedButton(
onPressed: () {
_controller.reset(); //重置
},
child: const Text("rest")),
ElevatedButton(
onPressed: () {
_controller.repeat(reverse:true); //重复播放 正序播放倒叙播放循环
},
child: const Text("repeat"))
],
),
)
],
),
);
}
}
链式操作修改动画效果
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
// TODO: implement initState
_controller = AnimationController(
vsync: this, //Vsync 机制可以理解为是显卡与显示器的通信桥梁,显卡在渲染每一帧之前会等待垂
// 直同步信号,只有显示器完成了一次刷新时,发出垂直同步信号,显卡才会渲染下一帧,确保刷新率和帧率保
// 持同步,以达到供需平衡的效果,防止卡顿现象。
duration: const Duration(seconds: 3),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Title'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SlideTransition(
position: Tween(
begin: const Offset(0, -1),
end: const Offset(0, 0.6) //表示实际的位置向右移动自身宽度的1.2倍
)
.chain(CurveTween(curve: Curves.bounceIn))
.chain(CurveTween(curve: const Interval(0.6, 0.8)))
//在_controller 到60%时开始,80%时结束
.animate(_controller),
child: const FlutterLogo(size: 80),
),
const SizedBox(
height: 40,
),
Padding(
padding: const EdgeInsets.fromLTRB(10, 0, 0, 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onPressed: () {
_controller.forward(); //正序播放一次
},
child: const Text("Forward")),
ElevatedButton(
onPressed: () {
_controller.reverse(); //倒序播放一次
},
child: const Text("Reverse")),
],
),
)
],
),
);
}
}
自定义动画AnimatedBuilder
运用场景 当组件有比较复杂的动画,比如缩放平移变淡等多个动画作用与一个widget时
child: AnimatedBuilder(
animation:_controller,
builder:(Buildcontext context,Widget child){
//第二个参数child作用是重新构建时,child不变,提升性能
return 0pacity(
opacity:Tween(begin:0.0,end:0.5).animated(_controller).value,
//上面是之前的链式调用写法
child: Container(
width: Tween(begin:200.0,end:300.0).evaluate(_controller),//一种写法
height:200 +100 *controller.value,//另一种写法
color: Colors.blue,
child: child,
),//Container
);// 0pacity
},
child: Center( //这里的child会插入到builder里面的child,作为不会变化的widget
child: Text(
"Hi”
style:TextStyle(fontSize:72)
),// Text
),// Center
),//AnimatedBuilder
当_animationController变化是,build函数会自动重新构建,相当于运行了setstate,源码实际上也是运行了setstate