Flutter 内置动画
上面的那些一般用起来不是很方便,即便是 AnimatedBuilder 还是要指定参与动画变化的 widget 属性,为了进一步方便我们,官方在
SlideTransition - 自身倍数位移动画AlignTransition - 没找到资料PositionedTransition - 缩放动画,限定父布局只能是 stackFadeTransition - 透明度动画ScaleTransition - 缩放动画,这个是 android 中的那种缩放动画,可以指定中心点SizeTransition - 宽高动画,限制是每次只能执行一个维度的动画,宽和高一起不行,那就是缩放动画了RotationTransition - 旋转动画,特点是其数值是 0-1 之间的,旋转90度 = 0.25
这些 transition 的特点就是,用一个参数接受 animation 动画,child 写 widget
FadeTransition
1 2 3 4 5 6 7 | animationController = AnimationController( duration: Duration(milliseconds: 300), vsync: this, ); animation = CurvedAnimation(parent: animationController, curve: Curves.bounceInOut); animation = Tween(begin: 0.0, end: 1.0).animate(animationController); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | Widget build(BuildContext context) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ FadeTransition( opacity: animation, child: Container( margin: EdgeInsets.only(bottom: 20), width: 300, height: 300, color: Colors.blueAccent, ), ), RaisedButton( child: Text("放大"), onPressed: () { animationController?.forward(); }, ), ], ), ); } } |
SlideTransition
1 2 3 4 5 6 7 8 9 10 11 | void initState() { super.initState(); animationController = AnimationController( duration: Duration(milliseconds: 300), vsync: this, ); animation = Tween(begin: Offset(0.0, 0.0), end: Offset(1.0, 1.0)) .animate(animationController); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | Widget build(BuildContext context) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ SlideTransition( position: animation, child: Container( margin: EdgeInsets.only(bottom: 20), width: 100, height: 100, color: Colors.blueAccent, ), ), RaisedButton( child: Text("放大"), onPressed: () { animationController?.forward(); }, ), ], ), ); } |
PositionedTransition
1 2 3 4 | animation = RelativeRectTween( begin: RelativeRect.fromLTRB(0, 0, 0, 0), end: RelativeRect.fromLTRB(50, 200, 50, 200)) .animate(animationController); |
大家看个图:
基本上就是这个思路了,限制有一些,下面是例子代码,不是上面 gif 的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | Animation<RelativeRect> animation; AnimationController animationController; CurvedAnimation curve; void initState() { super.initState(); animationController = AnimationController( duration: Duration(milliseconds: 300), vsync: this, ); curve = CurvedAnimation(parent: animationController, curve: Curves.bounceInOut); animation = RelativeRectTween( begin: RelativeRect.fromLTRB(0, 0, 0, 0), end: RelativeRect.fromLTRB(50, 200, 50, 200)) .animate(curve); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | Widget build(BuildContext context) { return Center( child: Stack( children: <Widget>[ PositionedTransition( rect: animation, child: Container( width: 300, height: 300, color: Colors.blueAccent, ), ), Positioned( top: 20, left: 20, child: RaisedButton( child: Text("放大"), onPressed: () { animationController?.forward(); }, ), ), ], ), ); } |
最后大家注意啊,RelativeRectTween begin 的数值能影响 widget 初始显示时的宽高大小
ScaleTransition
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | Animation<double> animation; AnimationController animationController; CurvedAnimation curve; @override void initState() { super.initState(); animationController = AnimationController( duration: Duration(milliseconds: 300), vsync: this, ); curve = CurvedAnimation(parent: animationController, curve: Curves.bounceInOut); animation = Tween( begin: 1.0, end: 0.3, ).animate(curve); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | Widget build(BuildContext context) { return Center( child: Stack( children: <Widget>[ ScaleTransition( alignment: Alignment.topLeft, scale: animation, child: Container( width: 300, height: 300, color: Colors.blueAccent, ), ), Positioned( top: 20, left: 20, child: RaisedButton( child: Text("放大"), onPressed: () { animationController?.forward(); }, ), ), ], ), ); } |
SizeTransition
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | Widget build(BuildContext context) { return Center( child: Stack( children: <Widget>[ SizeTransition( axis: Axis.horizontal, sizeFactor: animation, child: Container( color: Colors.blueAccent, child: Icon(Icons.access_alarm, size: 300), ), ), Positioned( top: 20, left: 20, child: RaisedButton( child: Text("放大"), onPressed: () { animationController?.forward(); }, ), ), ], ), ); } |
RotationTransition
1 2 3 4 | animation = Tween( begin: 0.0, end: 0.25, ).animate(curve); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | Widget build(BuildContext context) { return Center( child: Stack( children: <Widget>[ RotationTransition( turns: animation, alignment: Alignment.center, child: Container( color: Colors.blueAccent, child: Icon(Icons.access_alarm, size: 300), ), ), Positioned( top: 20, left: 20, child: RaisedButton( child: Text("放大"), onPressed: () { animationController?.forward(); }, ), ), ], ), ); } |