Flutter 动画基础与隐式动画

在本系列文章中,我们将向您介绍 Flutter 中的动画,并向您展示如何为您的 Flutter 应用程序构建简单和复杂的动画。

In this series of posts, we’re going to introduce you to animations in Flutter, and show you how to build both simple and complex animations for your Flutter app.

如果您愿意,这篇文章也可以作为视频使用。

This post is also available as a video, if you prefer.

在第一篇文章中,我们将专注于向您的应用程序添加动画的最直接方法。 您无需成为动画或动画术语方面的专家即可为您的应用添加动画。 在此过程中,我们将介绍一些小部件和术语,它们将帮助您立即开始使用动画,并为您提供本系列其余帖子的一些背景知识。

In this first post, we’re going to focus on the most straightforward way to add animations to your app. You don’t have to be an expert on animations or animation terminology to add animations to your app. Along the way, we’ll introduce some widgets and terminology that will help you get started with animations right away and give you some background for the rest of the posts in the series.

隐式动画小部件

Implicitly animated widgets

Flutter 包括一系列小部件,它们是您可能已经在应用中使用的现有小部件的动画版本,例如 Container 小部件的 AnimatedContainer 版本和 Positioned 小部件的 AnimatedPositioned 版本。

Flutter includes a series of widgets that are animated versions of existing widgets that you probably already used in your app, such as the AnimatedContainer version of the Container widget and the AnimatedPositioned version of the Positioned widget.

这些小部件会自动对其属性的更改进行动画处理。 当您使用新的属性值重建小部件时,例如使用 StatefulWidget 的 setState,小部件会处理将动画从前一个值驱动到新值。

These widgets automatically animate changes to their properties. When you rebuild the widget with new property values, such as with a StatefulWidget’s setState, the widget handles driving the animation from the previous value to the new value.

在这里插入图片描述
一个屏幕录制,其中修改了应用程序的代码并且应用程序为星形小部件的大小设置动画。

A screen recording where the code for an app is modified and the application animates the size of a star widget.

这些小部件称为隐式动画小部件。 当您需要向应用程序添加动画时,它们通常是您首先接触的东西。 它们提供了一种在不增加额外复杂性的情况下添加动画的方法。

These widgets are called Implicitly Animated Widgets. They are typically the first thing you reach for when you need to add animations to your app. They provide a way to add animations without adding additional complexity.

AnimatedContainer 小部件

The AnimatedContainer widget

让我们仔细看看如何使用这些隐式动画小部件之一为您的应用程序添加一些动画。

Let’s look a little closer at how you can use one of these implicitly animated widgets to add some animation to your app.

在这个应用程序中,有一个容器和一个按钮。 当按钮被按下时,setState 被调用,并且容器被重建为一个新的宽度值。 请注意,容器立即更改其宽度,没有任何动画。

In this app, there is a container and a button. When the button is pressed, setState is called, and the container is rebuilt with a new value for width. Notice that the container changes its width immediately, without any animation.

在这里插入图片描述
恒星会立即变大,其状态之间没有动画。

The star gets bigger instantly, with no animation between its states.

@override
Widget build(BuildContext context) {
  return Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: <Widget>[
      Container(
        width: _bigger ? 100 : 500,
        child: Image.asset('assets/star.png'),
      ),
      RaisedButton(
        onPressed: () => setState(() {
          _bigger = !_bigger;
        }),
        child: Icon(Icons.star),
      ),
    ],
  );
}

我们可以通过为 AnimatedContainer 小部件切换 Container 小部件并指定动画持续时间来向该应用程序添加一些动画。

We can add some animation to this app by switching the Container widget for an AnimatedContainer widget and specifying an animation duration.

AnimatedContainer(
  width: _bigger ? 100 : 500,
  child: Image.asset('assets/star.png'),
  duration: Duration(seconds: 1),
),

现在,当按下按钮时,容器会逐渐从先前的宽度值动画到新值。

Now, when the button is pressed, the container gradually animates from the previous width value to the new value.

在这里插入图片描述
星星现在在它的状态之间动画

The star now animates between its states

通过旧值和新值之间的值进行动画处理的过程称为插值。 AnimatedContainer 处理在旧值和新值更改时插入其属性。

The process of animating through the values between the old and new value is called interpolation. The AnimatedContainer handles interpolating its properties between the old and the new values whenever they change.

这适用于 AnimatedContainer 的所有属性,例如,包括 decoration。 我们可以修改装饰中的渐变,AnimatedContainer 处理在旧渐变和新渐变之间进行插值:

This applies to all of the AnimatedContainer’s properties, including, for example, the decoration. We can modify the gradient within a decoration and the AnimatedContainer handles interpolating between the old and new gradient:

AnimatedContainer(
  decoration: BoxDecoration(
    gradient: RadialGradient(
      colors: [Colors.purple, Colors.transparent],
      stops: [ _bigger ? 0.2 : 0.5, 1.0])
  ),
),

在这里插入图片描述
星星现在有一个动画渐变

The star now has an animated gradient

用duration和curves控制动画

Controlling the animation with duration and curves

像 AnimatedContainer 这样的隐式动画小部件有两个属性可以用来控制动画的行为。 您可以通过设置duration属性来控制插入新值所需的时间。

Implicitly animated widgets like AnimatedContainer have two properties that you can use to control the animation’s behavior. You can control how long it takes to interpolate to the new value by setting the duration property.

在这里插入图片描述

在这个例子中,我们让动画花费了更长的时间。

In this example, we made the animation take a much longer amount of time.

您还可以使用Curve来控制小部件从旧值插入到新值的方式。 曲线控制随时间的变化率,可以帮助您的动画感觉更逼真。 在这个例子中,我们将曲线从默认的线性曲线更改为更夸张的五次曲线:

You can also control the way the widget interpolates from the old to the new value by using a Curve. Curves control the rate of change over time and can help your animations feel more realistic. In this example, we changed the curve from the default linear curve to a more exaggerated quintic curve:

AnimatedContainer(
  width: _bigger ? 100 : 500,
  child: Image.asset('assets/star.png'),
  duration: Duration(seconds: 1),
  curve: Curves.easeInOutQuint,
),

在这里插入图片描述

在这里插入图片描述

左边是线性的,右边是五次的

Linear on the left, quintic on the right

有许多不同的内置曲线可以为您的动画赋予一些个性,您还可以定义自己的自定义曲线。 曲线甚至可以是不连续的,例如 SawTooth 曲线。

There are many different built-in Curves available to give your animations a bit of character, and you can also define your own custom curves. Curves can even be discontinuous, like the SawTooth curve.

下面是一个名为 SineCurve 的自定义曲线的示例,它使用正弦函数来制作一条会反弹的曲线:

Here’s an example of a custom curve called SineCurve that uses the sine function to make a curve that bounces:

class SineCurve extends Curve {
  final double count;
 
  SineCurve({this.count = 1});
 
  @override
  double transformInternal(double t) {
    return sin(count * 2 * pi * t) * 0.5 + 0.5;
  }
}

在这里插入图片描述

回顾一下

To recap

Flutter 提供隐式动画小部件,这些小部件是常见小部件的动画版本。 您可以使用持续时间和曲线来控制这些小部件的动画方式。

Flutter provides implicitly animated widgets that are animated versions of common widgets. You can control the way these widgets animate using durations and curves.

AnimatedContainer 是一个非常强大的隐式动画小部件,因为它有许多影响其外观的属性,并且所有这些属性都是自动插值的。

AnimatedContainer is one notably powerful implicitly animated widget because it has many properties that affect its appearance, and all of them are automatically interpolated.

所有其他隐式动画小部件也是功能强大、易于使用的选项,用于添加动画而不会增加很多复杂性。

All of the other implicitly animated widgets are also powerful, easy-to-use options for adding animations without adding a lot of complexity.

此外,您不一定需要将这些小部件放入 StatefulWidget 并使用 setState,您可以使用 StreamBuilderFutureBuilder 来触发动画,如本例所示。

Also, you don’t necessarily need to place these widgets into a StatefulWidget and use setState, you can use StreamBuilder and FutureBuilder to trigger animations like in this example.

深入研究动画

Digging deeper into animations

隐式动画小部件是您添加动画的首选,然而,这并不是 Flutter 动画系统必须提供的全部。 在本系列的其余部分,我们将探索 Flutter 动画系统的较低层,并向您展示如何直接使用动画系统构建高级动画。

Implicitly animated widgets are your first choice for adding animations, however, this isn’t all that Flutter’s animation system has to offer. In the rest of this series, we explore the lower layers of the Flutter animation system, and show you how you can build advanced animations by using the animation system directly.

对于其他一切,请访问 flutter.dev

For everything else, visit flutter.dev.

本系列文章:

Articles in this series:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值