Flutter-动画

555 阅读5分钟

实现

透明度渐变

Animation<double> opacity = Tween<double>(
begin: 0.0,
end: 1.0,
).animate(
CurvedAnimation(
parent: _controller,
curve: Interval(
0.0,
0.1,
curve: Curves.easeIn,
),
),
);

翻转


Animation<double> rotate = Tween<double>(
begin: 0.0,
end: math.pi * 2,
).animate(
CurvedAnimation(
parent: _controller,
curve: Interval(
0.0,
0.2,
curve: Curves.ease,
),
),
);

位移

Animation<EdgeInsets> movement = EdgeInsetsTween(
begin: EdgeInsets.only(top: 0.0),
end: EdgeInsets.only(top: 100.0),
).animate(
CurvedAnimation(
parent: _controller,
curve: Interval(
0.2,
0.375,
curve: Curves.fastOutSlowIn,
),
),
);

方形变圆

Animation<BorderRadius> radius = BorderRadiusTween(
begin: BorderRadius.circular(0.0),
end: BorderRadius.circular(100.0),
).animate(
CurvedAnimation(
parent: _controller,
curve: Interval(
0.5,
0.75,
curve: Curves.ease,
),
),
);

颜色渐变

Animation<Color> color = ColorTween(
begin: Colors.blue[300],
end: Colors.blue[900],
).animate(
CurvedAnimation(
parent: _controller,
curve: Interval(
0.5,
0.75,
curve: Curves.linear,
),
),
);

 

高宽渐变

Animation<double> height = Tween<double>(
begin: 100.0,
end: 200.0,
).animate(
CurvedAnimation(
parent: _controller,
curve: Interval(
0.375,
0.6,
curve: Curves.fastOutSlowIn,
),
),
);
Animation<double> width = Tween<double>(
begin: 100.0,
end: 200.0,
).animate(
CurvedAnimation(
parent: _controller,
curve: Interval(
0.375,
0.6,
curve: Curves.fastOutSlowIn,
),
),
);

 

组合

Widget _buildAni(BuildContext context, Widget child) {
return new Container(
padding: movement.value,
transform: Matrix4.identity()..rotateZ(rotate.value),
child: new Opacity(
opacity: opacity.value,
child: new Container(
width: width.value,
height: height.value,
decoration: new BoxDecoration(
color: color.value,
border: new Border.all(
color: Colors.black,
width: 3.0,
),
borderRadius: radius.value,
),
child: new Center(
child: new Text(
'staggered',
style: new TextStyle(color: Colors.white, fontSize: 16.0),
),
),
),
),
);
}
@override
Widget build(BuildContext context) {
return new Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new Padding(
padding:
const EdgeInsets.only(left: 10.0, top: 10.0, right: 10.0),
child: new FlatButton(
textColor: Colors.black,
child: new Text('replay staggered'),
onPressed: () {
_startAnimation();
}),
),
new AnimatedBuilder(animation: _controller, builder: _buildAni)
],
);
}

动画类型

• 补间(Tween)动画 :在补间动画中,定义了开始点和结束点、时间线以及定义转换时间和速度的曲线,然后由框架自动计算如何从开始点过渡到结束点。 flutterchina.club/animations/…

• 基于物理的动画 :在基于物理的动画中,运动被模拟为与真实世界的行为相似。例如,当你掷球时,它在何处落地,取决于抛球速度有多快、球有多重、距离地面有多远。 类似地,将连接在弹簧上的球落下(并弹起)与连接到绳子上的球放下的方式也是不同。 flutterchina.club/animations/…

常见的动画模式

• 动画列表或网格(AnimatedList flutterchina.club/catalog/sam…

• 共享元素转换(Hero 动画 flutterchina.club/animations/…)

• 交错动画

基本的动画概念和类

Animation对象:

Animation对象是Flutter动画库中的一个核心类,它生成指导动画的值。

Animation对象知道动画的当前状态(例如,它是开始、停止还是向前或向后移动),但它不知道屏幕上显示的内容。

Flutter中的Animation对象是一个在一段时间内依次生成一个区间之间值的类。Animation对象的输出可以是线性的、曲线的、一个步进函数或者任何其他可以设计的映射。 根据Animation对象的控制方式,动画可以反向运行,甚至可以在中间切换方向。

Animation还可以生成除double之外的其他类型值,如:Animation 或 Animation Animation对象有状态,可以通过访问其value属性获取动画的当前值

Animation对象本身和UI渲染没有任何关系

Interval

在[begin]之前为0.0的曲线,然后根据[curve曲线]在[end]时从0.0到1.0,然后是1.0。 可以使用[Interval]来延迟动画。例如,使用[Interval]将[begin]设置为0.5,将[end]设置为1.0的[Interval]使用[Interval],这6秒的动画将本质上变成三秒钟后开始的动画。

CurvedAnimation:将动画过程定义为一个非线性曲线,属于Animation类型 :

 final CurvedAnimation curve =

    new CurvedAnimation(parent: controller, curve: Curves.easeIn);

注: Curves 类类定义了许多常用的曲线,也可以创建自己的,例如:

class ShakeCurve extends Curve {

  @override

  double transform(double t) {

    return math.sin(t * math.PI * 2);

  }

}

AnimationController:

AnimationController是一个特殊的Animation对象,在屏幕刷新的每一帧,就会生成一个新的值,默认情况下,AnimationController在给定的时间段内会线性的生成从0.0到1.0的数字 属于Animation类型 具有控制动画的方法,例如,.forward()方法可以启动动画 当创建一个AnimationController时,需要传递一个vsync参数,存在vsync时会防止屏幕外动画(动画的UI不在当前屏幕时)消耗不必要的资源。 通过将SingleTickerProviderStateMixin添加到类定义中,可以将stateful对象作为vsync的值。如果要使用自定义的State对象作为vsync时,请包含TickerProviderStateMixin。 // 下面代码创建一个Animation对象,但不会启动它运行:

final AnimationController controller = new AnimationController(

    duration: const Duration(milliseconds: 2000), vsync: this);

Tween:

默认情况下,AnimationController对象的范围从0.0到1.0,使用Tween使动画可以生成不同的范围或数据类型的值。

Tween是一个无状态(stateless)对象,需要begin和end值,Tween的唯一作用就是定义从输入范围到输出范围的映射。

Tween继承自Animatable,而不是继承自Animation 。Animatable与Animation相似,不是必须输出double值。例如,ColorTween指定两种颜色之间的过渡。 evaluate(Animation animation)方法将映射函数应用于动画当前值,Animation对象的当前值可以通过value()方法取到。

要使用Tween对象,请调用其animate()方法,传入一个控制器对象(Tween.animate),注意animate()返回的是一个Animation,而不是一个Animatable。 / /以下示例,Tween生成从-200.0到0.0的值

final Tween doubleTween = new Tween<double>(begin: -200.0, end: 0.0);

// ColorTween指定两种颜色之间的过渡

final Tween colorTween =

    new ColorTween(begin: Colors.transparent, end: Colors.black54);

// 以下代码在500毫秒内生成从0到255的整数值

final AnimationController controller = new AnimationController(

    duration: const Duration(milliseconds: 500), vsync: this);

Animation alpha = new IntTween(begin: 0, end: 255).animate(controller);

// 以下示例构建了一个控制器、一条曲线和一个Tween:

final AnimationController controller = new AnimationController(

    duration: const Duration(milliseconds: 500), vsync: this);
final Animation curve =

    new CurvedAnimation(parent: controller, curve: Curves.easeOut);

Animation<int> alpha = new IntTween(begin: 0, end: 255).animate(curve);

动画通知

一个Animation对象可以拥有Listeners和StatusListeners监听器,可以用addListener()和addStatusListener()来添加

只要动画的值发生变化,就会调用监听器

动画开始、结束、向前移动或向后移动(如AnimationStatus所定义)时会调用StatusListener

一个Listener最常见的行为是调用setState()来触发UI重建。