Flutter 动画的基本使用
在使用Flutter动画的时候,我们通常使用这几个组件.
AnimationController,控制动画的抽象类Animation,给定值,转换为动画Tween, 执行范围AnimatedBuilder, 处理动画的Widget
首先使用有状态的StatefulWidget,创建AnimationController和Animation,并在initState中初始化这两个对象.
vsync需要使用with TickerProviderStateMixin,这样才是正常的进行动画的操作.
在initState方法中,声明这个动画执行时间为2秒.给animation添加一个监听事件,在动画完成后,将移除这个简单,并将AnimationController还原为初始状态,在执行一次动画.
AnimationController _controller;
Animation _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 2),
);
_animation = Tween(begin: -1.0, end: 0.0).animate(
CurvedAnimation(
parent: _controller,
curve: Curves.fastOutSlowIn,
),
)..addStatusListener(_handler);
}
_handler(status) {
if (status == AnimationStatus.completed) {
_animation.removeStatusListener(_handler);
_controller.reset();
_animation = Tween(begin: 0.0, end: 1.0).animate(
CurvedAnimation(parent: _controller, curve: Curves.fastOutSlowIn),
)..addStatusListener(
(status) {
if (status == AnimationStatus.completed) {
Navigator.pop(context);
}
},
);
_controller.forward();
}
}在build方法,使用AnimatedBuilder控件来对动画进行控制和处理,其中animation绑定之前定义的AnimationController.
Transform控件可以将动画执行中的变量值处理反馈在子控件上.
Matrix4.translationValues这里将子控件在x轴上进行平移.
通过AnimationController的forward()方法来执行动画.
@override
Widget build(BuildContext context) {
final double width = MediaQuery.of(context).size.width;
_controller.forward();
return Scaffold(
appBar: AppBar(
title: Text(widget.toString()),
),
body: AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return Transform(
transform: Matrix4.translationValues(
_animation.value * width,
0.0,
0.0,
),
child: Center(
child: Container(
width: 200.0,
height: 200.0,
color: Colors.blue,
),
),
);
},
),
);
}最后一定要将AnimationController进行销毁.
@override
void dispose() {
_controller.dispose();
super.dispose();
}下面就是刚刚的效果.
偏移和延迟代码还是按照上面的代码来,执行三个控件,并将其中一个延迟执行.
实现延迟操作,需要使用Interval来进行操作,Interval是一个可以返回CurveAnimation的一个类,设置begin和end的值,让动画知道在哪个点才开始执行.
AnimationController _controller;
Animation _animation, _lateAnimation;
@override
void initState() {
// TODO: implement initState
super.initState();
_controller =
AnimationController(vsync: this, duration: Duration(seconds: 2));
_animation = Tween(begin: -1.0, end: 0.0).animate(
CurvedAnimation(
parent: _controller,
curve: Curves.fastOutSlowIn,
),
)..addStatusListener(_handler);
_lateAnimation = Tween(begin: -1.0, end: 0.0).animate(
CurvedAnimation(
parent: _controller,
curve: Interval(0.2, 1.0, curve: Curves.fastOutSlowIn),
),
);
}
_handler(status) {
if (status == AnimationStatus.completed) {
_animation.removeStatusListener(_handler);
_controller.reset();
_animation = Tween(begin: 0.0, end: 1.0).animate(
CurvedAnimation(
parent: _controller,
curve: Curves.fastOutSlowIn,
),
);
_lateAnimation = Tween(begin: 0.0, end: 1.0).animate(
CurvedAnimation(
parent: _controller,
curve: Interval(0.2, 1.0, curve: Curves.fastOutSlowIn),
),
)..addStatusListener((status) {
if (status == AnimationStatus.completed) {
Navigator.pop(context);
}
});
_controller.forward();
}
}
@override
Widget build(BuildContext context) {
final double width = MediaQuery.of(context).size.width;
_controller.forward();
return Scaffold(
appBar: AppBar(
title: Text(widget.toString()),
),
body: AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return Center(
child: Column(
children: <Widget>[
Transform(
transform: Matrix4.translationValues(
_animation.value * width, 0.0, 0.0),
child: Container(
margin: EdgeInsets.all(10),
width: 200,
height: 50,
color: Colors.red,
),
),
Transform(
transform: Matrix4.translationValues(
_animation.value * width, 0.0, 0.0),
child: Container(
margin: EdgeInsets.all(10),
width: 200,
height: 50,
color: Colors.red,
),
),
Transform(
transform: Matrix4.translationValues(
_lateAnimation.value * width, 0.0, 0.0),
child: Container(
margin: EdgeInsets.all(10),
width: 200,
height: 50,
color: Colors.red,
),
),
],
),
);
},
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}来看看效果.
这里使用BorderRadiusTween来完成一个空间的转换动画,圆形转方形.
这里将初始化设为50的一个圆,BorderRadiusTween设置圆的弧度.
AnimationController controller;
Animation animation, borderAnimation;
@override
void initState() {
super.initState();
controller = AnimationController(
vsync: this,
duration: Duration(milliseconds: 2000),
)..addStatusListener((status) {
if (status == AnimationStatus.completed) {
controller.reverse();
}
if (status == AnimationStatus.dismissed) {
Navigator.pop(context);
}
});
animation = Tween(begin: 50.0, end: 200.0).animate(
CurvedAnimation(
parent: controller,
curve: Curves.ease,
),
);
borderAnimation = BorderRadiusTween(
begin: BorderRadius.circular(75.0),
end: BorderRadius.circular(0.0),
).animate(CurvedAnimation(
parent: controller,
curve: Curves.ease,
));
controller.forward();
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.toString()),),
body: AnimatedBuilder(animation: controller, builder: (context, child) {
return Center(
child: Container(
width: animation.value,
height: animation.value,
decoration: BoxDecoration(
borderRadius: borderAnimation.value,
color: Colors.pink,
),
),
);
}),
);
}



