Flutter 动画教程

本教程向您展示如何在Flutter中构建显式动画。在介绍了动画库中的一些基本概念、类和方法之后,它将带您浏览5个动画示例。这些示例相互构建,向您介绍动画库的不同方面。

Flutter SDK还提供了过渡动画,比如FadeTransitionSizeTransitionSlideTransition。这些简单的动画通过设置起点和终点来触发。它们比这里描述的显式动画更容易实现。

基本的动画概念和类

Flutter中的动画系统是基于类型化的动画对象。微件(widget)可以通过读取它们的当前值并侦听它们的状态变化,直接将这些动画合并到它们的构建函数中,也可以使用这些动画作为传递给其他微件的更精细动画的基础。

Animation

在Flutter中,动画对象对屏幕上的内容一无所知。Animation是一个抽象类,它理解当前值及其状态(完成或取消)。比较常用的动画类型之一是Animation <double>

Animation对象在一定的持续时间内连续地在两个值之间生成插值数。Animation对象的输出可以是线性的、曲线的、阶跃函数的,或者您可以设计的任何其他映射。根据Animation对象的控制方式,它可以反向运行,甚至在中间切换方向。

动画还可以插入除double之外的类型,比如Animation<Color>Animation<Size>

Animation对象具有状态。它的当前值始终在.value成员中可用。

Animation对象对呈现或build()函数一无所知。

CurvedAnimation

CurvedAnimation将动画的进度定义为非线性曲线。

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

注意:
Curves类定义了许多常用的曲线,或者您可以创建自己的曲线。例如:

import 'dart:math';
class ShakeCurve extends Curve {
 @override
 double transform(double t) => sin(t * pi * 2);
}

CurvedAnimationAnimationController(在下一节中描述)都是Animation<double>的子类,因此可以互换传递它们。CurvedAnimation封装了它正在修改的对象——你不需要子类化AnimationController来实现曲线。

AnimationController

AnimationController是一个特殊的Animation对象,每当硬件准备好创建一个新帧时,它都会生成一个新值。默认情况下,AnimationController在给定的持续时间内线性生成0.0到1.0之间的数字。例如,这段代码创建了一个动画对象,但是没有让它运行:

controller =
    AnimationController(duration: const Duration(seconds: 2), vsync: this);

AnimationController派生自Animation<double>,因此它可以用于任何需要动画对象的地方。然而,AnimationController有额外的方法来控制动画。例如,使用.forward()方法启动动画。生成数字与屏幕刷新相关联,因此通常每秒生成60个数字。在生成每个数字之后,每个动画对象都会调用附加的侦听器对象。要为每个子元素创建自定义显示列表,请参见RepaintBoundary

在创建AnimationController时,要传递一个vsync参数。vsync的存在可以防止屏幕外动画消耗不必要的资源。通过在类定义中添加SingleTickerProviderStateMixin,您可以使用您的有状态对象作为vsync。你可以在GitHub上的animate1中看到这样一个例子。

注意:
在某些情况下,位置可能会超过AnimationController的0-1.0范围。例如,fling()函数 允许您提供速度、力和位置(通过Force对象)。该位置可以是0.0到1.0范围之外的任何位置。

即使AnimationController没有,CurvedAnimation动画也可以超过0.0到1.0的范围。根据所选择的曲线,CurvedAnimation的输出可以比输入具有更大的范围。例如,弹性曲线CurveselasticIn将明显超过或低于默认范围。

Tween

默认情况下,AnimationController对象的范围从0.0到1.0。如果需要不同的范围或不同的数据类型,可以使用Tween来配置动画,以插入到不同的范围或数据类型。例如,下面的Tween从-200.0到0.0:

tween = Tween<double>(begin: -200, end: 0);

Tween是一个无状态对象,只接受beginendTween的唯一工作是定义一个从输入范围到输出范围的映射。输入范围通常是0.0到1.0,但这不是必需的。

Tween继承自Animatable<T>,而不是Animation<T>。像Animation一样Animatable不需要输出double。例如,ColorTween指定了两种颜色之间的进程。

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

Tween对象不存储任何状态。相反,它提供了evaluate(Animation<double> animation)方法,该方法将映射函数应用于动画的当前值。Animation对象的当前值可以在.value方法中找到。evaluate函数还执行一些内务管理,比如确保在动画值分别为0.0和1.0时返回beginend

Tween.animate

要使用Tween对象,在Tween上调用animate(),传入控制器对象。例如,下面的代码在500毫秒的时间内生成从0到255的整数值。

AnimationController controller = AnimationController(
    duration: const Duration(milliseconds: 500), vsync: this);
Animation<int> alpha = IntTween(begin: 0, end: 255).animate(controller);

注意:
animate() 方法返回 Animation对象而不是 Animatable对象。

下面的例子展示了一个controller, 一个 curve, 和一个Tween:

AnimationController controller = AnimationController(
    duration: const Duration(milliseconds: 500), vsync: this);
final Animation curve =
    CurvedAnimation(parent: controller, curve: Curves.easeOut);
Animation<int> alpha = IntTween(begin: 0, end: 255).animate(curve);

Animation 通知

Animation对象可以有侦听器和状态侦听器,它们由addListener()addStatusListener()定义。每当动画的值发生变化时,就会调用侦听器。侦听器最常见的行为是调用setState()来重新构建。当动画开始、结束、向前移动或向后移动(由AnimationStatus定义)时,将调用StatusListener。下一节有一个addListener()方法的例子,监视动画的进度显示了一个addStatusListener()的例子。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值