Flutter开发者

Flutter动画【2】

2018-05-15

前言

在上次的文章中我们学习了Tween动画的用法,我们也一块看了下AnimatedBuilder和AnimatedWidget的用法,通过Tween动画结合相应的Wdiget属性我们可以做出我们想要的效果,但是在一般的场景下,这样做事比较麻烦的。因为我们每次都要侯建这个Animation并且与Widget的属性相绑定。

所以在一般情况下我们并不直接使用Animation。

AnimationWidgets

在Flutter内部为们提供了很多的动画Wdiget,比如AnimatedContainer、AnimatedCrossFade、AnimatedOpacity、AnimatedSize、AnimatedPositioned等等。

现在我们看下如何来使用这些基于动画的Widget

AnimatedContainer

AnimatedContainer看名字不难知道它是Container的动画版本,使用AnimatedContainer就不需要再创建Animation了。

AnimatedContainer继承于ImplicitlyAnimatedWidget,相应的我们需要传入动画的播放时间(必须填写)和插值器类型(有默认值)

然后,我们就可以让AnimatedContainer根据我们的值来做动画效果并且作用到相应的属性上。

所以还是看个例子吧

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
import 'package:flutter/animation.dart';
import 'package:flutter/material.dart';

void main() {
runApp(new MaterialApp(home: LogoFade(),));
}

class LogoFade extends StatefulWidget {
@override
createState() => new LogoFadeState();
}

class LogoFadeState extends State<LogoFade> {
double animValue = 100.0;

_changeValue() {
setState(() => animValue = animValue == 0 ? 100.0 : 0.0);
}

@override
Widget build(BuildContext context) {
return new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
new AnimatedContainer(
curve: Curves.bounceOut,
duration: new Duration(seconds: 3),
child: new FlutterLogo(size: 100.0,),
padding: EdgeInsets.only(bottom: animValue),
),
SizedBox(height: 30.0,),
new RaisedButton(
child: new Text('GO'),
onPressed: _changeValue,
),
],
);
}
}

可以看见我们在Column的第一个Widget中放了一个AnimatedContainer,指定了插值器的类型为Curves.bounceOut并且指定动画时长为3秒。

我们设置AnimatedContainer的底部padding的默认值为100.0,这样动画就会根据我们设置的值去改变底部padding,当我们点击按钮时就会改变设置的padding值来从新开始动画。

当然,大家可以试下其他属性比如颜色、大小等。

AnimatedOpacity

接下来我们来看下改变透明度的动画Widget,可以child根据设置的时间和动画范围改变透明度

同样的AnimatedOpacity也继承于ImplicitlyAnimatedWidget,需要填入Curve和Duration参数。

依旧来看代码吧:

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
import 'package:flutter/animation.dart';
import 'package:flutter/material.dart';

/**
* 使用AnimatedBuilder来做动画
*/

void main() {
runApp(new MaterialApp(home: LogoFade(),));
}

class LogoFade extends StatefulWidget {
@override
createState() => new LogoFadeState();
}

class LogoFadeState extends State<LogoFade> {
double opacityLevel = 0.0;

_changeOpacity() {
setState(() => opacityLevel = opacityLevel == 0 ? 1.0 : 0.0);
}

@override
Widget build(BuildContext context) {
return new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
new AnimatedOpacity(

duration: new Duration(seconds: 3),
child: new FlutterLogo(size: 100.0,),
opacity: opacityLevel,
curve: Curves.linear,
),
SizedBox(height: 30.0,),
new RaisedButton(
child: new Text('GO'),
onPressed: _changeOpacity,
),
],
);
}
}

上面的代码类似,我们在Column的第一个元素上放置了一个AnimatedOpacity,指定动画的插值器类型为线性的,指定动画时长为3秒,透明度的最小值为0.0。

当我们点击按钮时,透明度的值就会在0.0到1.0之间切换了。

AnimatedCrossFade

AnimatedCrossFade允许一个Widget到另为一个Widget使用渐变的改变。
与 AnimatedOpacity和AnimatedContainer不同,AnimatedCrossFade直接继承于StatefulWidget,构造方法必须要传入两个不同的Widget,当然你也可以指定每个widget的动画差值器。

来看下效果吧。

其实就是类似于视频编辑时第一帧到第二帧渐变动画而已。

好吧,还是来看下如何实现。

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
import 'package:flutter/animation.dart';
import 'package:flutter/material.dart';


void main() {
runApp(new MaterialApp(home: LogoFade(),));
}

class LogoFade extends StatefulWidget {
@override
createState() => new LogoFadeState();
}

class LogoFadeState extends State<LogoFade> {
bool _first = true;

_changeOpacity() {
setState(() => _first = _first == false ? true : false);
}

@override
Widget build(BuildContext context) {
return new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
new AnimatedCrossFade(
duration: const Duration(seconds: 3),
firstChild: const FlutterLogo(style: FlutterLogoStyle.horizontal, size: 100.0),
secondChild: const FlutterLogo(style: FlutterLogoStyle.stacked, size: 200.0),
crossFadeState: _first ? CrossFadeState.showFirst : CrossFadeState.showSecond,
),
SizedBox(height: 30.0,),
new RaisedButton(
child: new Text('GO'),
onPressed: _changeOpacity,
),
],
);
}
}

我们定义了两个FlutterLogo,使用不同的大小和logio样式,让AnimatedCrossFade来处理中间的过渡,我们并不需要关心中间的过程。

小结

使用系统提供的AnimationWidgets可以很方便的实现Widget的动画效果,在做一些简单的动画时还是非常有用的,当然在flutter中还为我们提供很多其他的动画效果如AnimatedPositioned、AnimatedSize、SlideTransition、SizeTransition、ScaleTransition、otationTransition等动画效果,前两者与今天讲到的类似,其他的类似于上期的AnimatedWidget用法,大家在下面可以多试试哦。

使用支付宝打赏
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

打赏请备注姓名或者昵称,方便我后期统计哦

关注公众号,及时查阅最新文章