动画效果介绍

精心设计的动画会使 UI 更生动,它有助于提升应用程序更精巧的外观和感觉,从而改善用户体验。 Flutter 让各种动画效果的实现变得容易。在许多 widget 特别是 Material widgets 中,它们都自带其设计规范中定义的标准动画效果,当然,你也可以定制这些效果。

选择一种实现方式

#

在 Flutter 中创建动画可以有多种不同实现方式。那么,究竟哪种才是最适合你的呢?为了帮助你更好的理解它,你可以观看下面的视频, 如何在 Flutter 中选择合适的动画 Widget (同时也发布了一篇 配套文章。)


How to choose which Flutter animation widget is right for your use case

(若想要深入了解它的决策流程,请观看在 Flutter Europe 社区账号发布的 在 Flutter 中使用动画的正确选择)视频。

正如视频中说的那样,下面的决策树将帮助你挑选实现 Flutter 动画的正确方式:

The animation decision tree

深入了解动画

#

要深入了解 Flutter 中的动画是如何工作的,请观看视频 Animation deep dive。(同时也发表了 配套文章)。


隐式动画和显式动画

#

内置的隐式动画

#

如果内置的隐式动画(最简单的动画)已经能够满足你的需求,请观看 隐式动画基础。(同时也发布了一篇 配套文章。)


Flutter 隐式动画动画基础知识

自定义隐式动画

#

要创建一个自定义的隐式动画,请观看 使用 TweenAnimationBuilder 创建独特的隐式动画。(同时也发布了一篇 配套文章。)


使用 TweenAnimationBuilder 创建自定义隐式动画

内置的显式动画

#

要创建显式动画(手动控制,而不是让框架控制),你可以使用内置的其中一个显式动画类来实现。更多有关信息,请观看 使用内置显式动画。(同时也发布了一篇 配套文章。)


显式动画

#

如果你需要从头开始构建显式动画,请观看 通过 AnimatedBuilder 和 AnimatedWidget 创建一个自定义动画。(同时也发布了一篇 配套文章。)


动画类型

#

动画分为两类:补间动画和基于物理动画。下面将解释这些术语的含义,并帮助你找到更多相关资源。在一些情况下,我们现有的最佳文档是 Flutter gallery 中的示例代码。

补间动画

#

补间动画是“介于两者之间”的缩写。在补间动画中,定义了起点和终点以及时间轴,再定义过渡时间和速度的曲线。然后框架会计算如何从起点过渡到终点。

基于物理基础的动画

#

在基于物理基础的动画中,动作是模拟真实世界的行为来进行建模的。举个例子,当你抛球时,球落地的时间和位置取决于抛出的速度和距离地面的高度。类似地,附在弹簧上的球和附在绳子上的球掉落(和反弹)方式是不一样的。

常见动画模式

#

大多数 UX 或动效设计师在设计 UI 时都会寻找主要动画模式。本章的列表将介绍一些常见的动画模式,并向你介绍更多学习它们的地方。

列表或网格动画

#

这种模式用于在列表或网格中添加或删除元素。

  • AnimatedList example
    这个来自 Sample app catalog 的演示展示了如何动态添加元素至列表或删除选定元素。当用户使用 plus (+) 和 minus (-) 按钮修改列表时,会同步到内部 Dart 列表。

共享元素转换

#

在这个模式中,用户从页面中选择一个元素,通常是图像,然后 UI 会在新页面中为指定元素添加动画,并生成更多细节。在 Flutter 中,你可以通过 Hero widget 轻松实现路径(页面)间的共享元素转换动画。

  • Hero animations 如何创建两种风格的 Hero 动画:

    • 当改变位置和大小时,Hero 从一页飞至另一页。

    • Hero 的边界改变形状由圆变方,同时从一页飞至另一页。

  • 另请参阅 API 文档 HeroNavigatorPageRoute 类。

交织动画

#

动画被分解成较小的动作,其中一些动作被延迟。这些小动画可以是连续的,也可以部分或完全重叠。

Essential animation concepts and classes

#

The animation system in Flutter is based on typed Animation objects. Widgets can either incorporate these animations in their build functions directly by reading their current value and listening to their state changes or they can use the animations as the basis of more elaborate animations that they pass along to other widgets.

Animation<double>

#

In Flutter, an Animation object knows nothing about what is onscreen. An Animation is an abstract class that understands its current value and its state (completed or dismissed). One of the more commonly used animation types is Animation<double>.

An Animation object sequentially generates interpolated numbers between two values over a certain duration. The output of an Animation object might be linear, a curve, a step function, or any other mapping you can create. Depending on how the Animation object is controlled, it could run in reverse, or even switch directions in the middle.

Animations can also interpolate types other than double, such as Animation<Color> or Animation<Size>.

An Animation object has state. Its current value is always available in the .value member.

An Animation object knows nothing about rendering or build() functions.

CurvedAnimation

#

A CurvedAnimation defines the animation's progress as a non-linear curve.

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

CurvedAnimation and AnimationController (described in the next sections) are both of type Animation<double>, so you can pass them interchangeably. The CurvedAnimation wraps the object it's modifying—you don't subclass AnimationController to implement a curve.

You can use Curves with CurvedAnimation. The Curves class defines many commonly used curves, or you can create your own. For example:

dart
import 'dart:math';

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

If you want to apply an animation curve to a Tween, consider using CurveTween.

AnimationController

#

AnimationController is a special Animation object that generates a new value whenever the hardware is ready for a new frame. By default, an AnimationController linearly produces the numbers from 0.0 to 1.0 during a given duration. For example, this code creates an Animation object, but does not start it running:

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

AnimationController derives from Animation<double>, so it can be used wherever an Animation object is needed. However, the AnimationController has additional methods to control the animation. For example, you start an animation with the .forward() method. The generation of numbers is tied to the screen refresh, so typically 60 numbers are generated per second. After each number is generated, each Animation object calls the attached Listener objects. To create a custom display list for each child, see RepaintBoundary.

When creating an AnimationController, you pass it a vsync argument. The presence of vsync prevents offscreen animations from consuming unnecessary resources. You can use your stateful object as the vsync by adding SingleTickerProviderStateMixin to the class definition. You can see an example of this in animate1 on GitHub.

Tween

#

By default, the AnimationController object ranges from 0.0 to 1.0. If you need a different range or a different data type, you can use a Tween to configure an animation to interpolate to a different range or data type. For example, the following Tween goes from -200.0 to 0.0:

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

A Tween is a stateless object that takes only begin and end. The sole job of a Tween is to define a mapping from an input range to an output range. The input range is commonly 0.0 to 1.0, but that's not a requirement.

A Tween inherits from Animatable<T>, not from Animation<T>. An Animatable, like Animation, doesn't have to output double. For example, ColorTween specifies a progression between two colors.

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

A Tween object doesn't store any state. Instead, it provides the evaluate(Animation<double> animation) method that uses the transform function to map the current value of the animation (between 0.0 and 1.0), to the actual animation value.

The current value of the Animation object can be found in the .value method. The evaluate function also performs some housekeeping, such as ensuring that begin and end are returned when the animation values are 0.0 and 1.0, respectively.

Tween.animate

#

To use a Tween object, call animate() on the Tween, passing in the controller object. For example, the following code generates the integer values from 0 to 255 over the course of 500 ms.

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

The following example shows a controller, a curve, and a Tween:

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

Animation notifications

#

An Animation object can have Listeners and StatusListeners, defined with addListener() and addStatusListener(). A Listener is called whenever the value of the animation changes. The most common behavior of a Listener is to call setState() to cause a rebuild. A StatusListener is called when an animation begins, ends, moves forward, or moves reverse, as defined by AnimationStatus.

Codelabs, tutorials, and articles

#

The following resources are a good place to start learning the Flutter animation framework. Each of these documents shows how to write animation code.

  • Implicit animations codelab
    Covers how to use implicit animations using step-by-step instructions and interactive examples.

  • Animations tutorial
    Explains the fundamental classes in the Flutter animation package (controllers, Animatable, curves, listeners, builders), as it guides you through a progression of tween animations using different aspects of the animation APIs. This tutorial shows how to create your own custom explicit animations.

  • Zero to One with Flutter, part 1 and part 2
    Medium articles showing how to create an animated chart using tweening.

  • Write your first Flutter app on the web
    Codelab demonstrating how to create a form that uses animation to show the user's progress as they fill in the fields.

  • Casual games toolkit
    A toolkit with game templates that contain examples of how to use Flutter animations.

其他资源

#

以下链接可以了解更多 Flutter 动画: