基本概念
- Animation对象是Flutter动画库中的一个核心类,它生成指导动画的值。
- Animation对象知道动画的当前状态(例如,它是开始、停止还是向前或向后移动),但它不知道屏幕上显示的内容。
- AnimationController管理Animation。
- CurvedAnimation 将过程抽象为一个非线性曲线.
- Tween在正在执行动画的对象所使用的数据范围之间生成值。例如,Tween可能会生成从红到蓝之间的色值,或者从0到255。
- 使用Listeners和StatusListeners监听动画状态改变。
Tween的使用
展示了一个自定义button,使用opacity,淡入淡出button的文字。
import 'package:flutter/foundation.dart';
import 'package:flutter/import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class FancyButton extends StatelessWidget{
final GestureTapCallback onPressed;
FancyButton({ this.onPressed});
Widget build(BuildContext context) {
return new RawMaterialButton(
fillColor: Colors.deepOrange,
splashColor: Colors.orange,
shape: new StadiumBorder(),
onPressed: (){
},
child: Padding(
padding: const EdgeInsets.symmetric(
vertical:8.0,
horizontal:10.0,
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: const <Widget>[
RotatedBox(
quarterTurns: 2,
child: Icon(Icons.explore,
color:Colors.amber,
),
),
SizedBox(width: 8.0,),
PulseAnimator(
child: Text(
"PUCHASE",
style: TextStyle(
color: Colors.white
),
),
),
],
),
)
);
}
}
class PulseAnimator extends StatefulWidget {
final Widget child;
const PulseAnimator({Key key,this.child}) : super(key:key);
_PulseAnimatorState createState() => _PulseAnimatorState();
}
class _PulseAnimatorState extends State<PulseAnimator> with SingleTickerProviderStateMixin{
AnimationController _controller;
void initState(){
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 2), //动画时长2s
vsync: this,
)..repeat(); //循环
}
void dispose(){
_controller.dispose();
super.dispose();
}
Widget build(BuildContext context) {
return FadeTransition(
// 透明度从0.5-1.0
opacity: new Tween(begin: 0.5,end: 1.0).animate(_controller),
child: widget.child,
);
}
}
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
分离动画代码
AnimatedWidget类允许您从setState()调用中的动画代码中分离出widget代码。AnimatedWidget不需要维护一个State对象来保存动画。
import 'package:flutter/material.dart';
import 'package:flutter/animation.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
MyAppState createState() => MyAppState();
}
class MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
Animation animation;
AnimationController animationController;
void initState() {
super.initState();
animationController = AnimationController(
duration: Duration(milliseconds: 2000), vsync: this);
animation = Tween(begin: 0.0, end: 400.0).animate(animationController);
animation.addStatusListener((status) {
if (status == AnimationStatus.completed) {
animationController.reverse();
} else if (status == AnimationStatus.dismissed) {
animationController.forward();
}
});
animationController.forward();
}
Widget build(BuildContext context) {
return LogoAnimation(
animation: animation,
);
}
void dispose() {
animationController.dispose();
super.dispose();
}
}
/// 动画继承AnimatedWidget
class LogoAnimation extends AnimatedWidget {
LogoAnimation({Key key, Animation animation})
: super(key: key, listenable: animation);
Widget build(BuildContext context) {
Animation animation = listenable;
return MaterialApp(
title: "Animation",
home : Scaffold(
appBar: AppBar(
title: Text("Animation"),
),
body: Center(
child: Container(
height: animation
.value,
width: animation.value,
child: FlutterLogo(),
),
),
),
);
}
}
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Curve动画使用
import 'package:flutter/material.dart';
class Loader extends StatefulWidget {
State createState() => new LoaderState();
}
class LoaderState extends State<Loader> with SingleTickerProviderStateMixin {
AnimationController animationController;
Animation<double> animation;
void initState() {
super.initState();
animationController = new AnimationController(duration: new Duration(milliseconds: 1750), vsync: this);
animation = new CurvedAnimation(parent: animatiobounceInnController, curve: Curves.elasticIn)
..addListener(() => this.setState(() {}))
..addStatusListener((AnimationStatus status) {
});
animationController.repeat();
}
void dispose() {
animationController.dispose();
super.dispose();
}
Widget build(BuildContext context) {
return Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Container(
color: Colors.white,
width: animation.value * 100.0,
height: 3.0,
),
new Padding(padding: new EdgeInsets.only(bottom: 5.0),),
new Container(
color: Colors.white,
width: animation.value * 75.0,
height: 3.0,
),
new Padding(padding: new EdgeInsets.only(bottom: 5.0),),
new Container(
color: Colors.white,
width: animation.value * 50.0,
height: 3.0,
),
new Padding(padding: new EdgeInsets.only(bottom: 5.0),),
],
),
);
}
}
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
hero animation
login page animation sample
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return new MaterialApp(
theme: new ThemeData(primarySwatch: Colors.blue),
home: new LoginPage(),
);
}
}
class LoginPage extends StatefulWidget {
State createState() => new LoginPageState();
}
class LoginPageState extends State<LoginPage>
with SingleTickerProviderStateMixin {
Animation<double> _iconAnimation;
AnimationController _iconAnimationController;
void initState() {
super.initState();
_iconAnimationController = new AnimationController(
vsync: this, duration: new Duration(milliseconds: 1000));
_iconAnimation = new CurvedAnimation(
parent: _iconAnimationController,
curve: Curves.bounceOut,
);
_iconAnimation.addListener(() => this.setState(() {}));
_iconAnimationController.forward();
}
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Colors.white,
body: new Stack(fit: StackFit.expand, children: <Widget>[
new Image(
image: new AssetImage("assets/girl.jpeg"),
fit: BoxFit.cover,
colorBlendMode: BlendMode.darken,
color: Colors.black87,
),
new Theme(
data: new ThemeData(
brightness: Brightness.dark,
inputDecorationTheme: new InputDecorationTheme(
// hintStyle: new TextStyle(color: Colors.blue, fontSize: 20.0),
labelStyle:
new TextStyle(color: Colors.tealAccent, fontSize: 25.0),
)),
isMaterialAppTheme: true,
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new FlutterLogo(
size: _iconAnimation.value * 140.0,
),
new Container(
padding: const EdgeInsets.all(40.0),
child: new Form(
autovalidate: true,
child: new Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new TextFormField(
decoration: new InputDecoration(
labelText: "Enter Email", fillColor: Colors.white),
keyboardType: TextInputType.emailAddress,
),
new TextFormField(
decoration: new InputDecoration(
labelText: "Enter Password",
),
obscureText: true,
keyboardType: TextInputType.text,
),
new Padding(
padding: const EdgeInsets.only(top: 20.0),
),
new MaterialButton(
height: 50.0,
minWidth: 150.0,
color: Colors.green,
splashColor: Colors.teal,
textColor: Colors.white,
child: new Icon(FontAwesomeIcons.signInAlt),
onPressed: () {},
)
],
),
),
)
],
),
),
]),
);
}
}
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
colors loader
参考资料
- https://medium.com/@nhancv/flutter-curves-simulation-f935bb225ad2
- https://flutterchina.club/tutorials/animation/#%E7%94%A8animatedwidget%E7%AE%80%E5%8C%96