Flutter动画基础,隐式动画

281 阅读4分钟

在第一篇文章中,我们将重点介绍最简单的方法来为你的应用程序添加动画。你不必是动画或动画术语方面的专家才能将动画添加到你的应用程序中。在此过程中,我们将介绍一些小部件和术语,这些小部件和术语将帮助您立即开始使用动画,并为本系列余下的文章提供一些背景知识。

隐式动画控件

Flutter包含一系列小部件,它们是可能已经在应用程序中使用的现有小部件的动画版本,例如容器小部件的AnimatedContainer版本和定位小部件的AnimatedPositioned版本。 这些小部件会自动对其属性进行更改。当您使用新的属性值(例如使用StatefulWidget的setState)重建小部件时,小部件处理将动画从以前的值驱动到新值的过程。

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

AnimatedContainer控件

让我们仔细看看如何使用这些隐式动画小部件向应用程序添加动画。 在这个应用程序中,有一个容器和一个按钮。当按下按钮时,将调用setState,并使用新的宽度值重建容器。请注意,容器会立即更改其宽度,而不会出现任何动画。

@overrideWidget 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小部件的容器小部件并指定一个动画持续时间来为这个应用程序添加一些动画。

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

现在,当按钮被按下时,容器将从以前的“宽度”值逐渐变为新的“宽度”值。

通过新旧值之间的值设置动画的过程称为插值。AnimatedContainer在旧值和新值发生更改时处理其属性的插值。 这适用于AnimatedContainer的所有属性,例如,包括装饰。我们可以在装饰中修改渐变,动画容器控制柄在新旧渐变之间插值。

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

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

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

在本例中,我们使动画花费更长的时间。 您还可以通过使用曲线来控制小部件从旧值到新值的插值方式。曲线控制随时间变化的速率,可以帮助您的动画感觉更真实。在本例中,我们将曲线从默认的线性曲线更改为更夸张的五次曲线:

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

有许多不同的内置曲线可以给你的动画一点字符,你也可以定义你自己的自定义曲线。曲线甚至可以是不连续的,比如锯齿曲线。 下面是一个名为SineCurve的自定义曲线的示例,它使用sine函数来生成一条反弹的曲线:

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;
  }
}

重述 

Flutter提供隐式动画控件,这些控件是常见控件的动画版本。您可以使用持续时间和曲线控制这些小部件的动画方式。 AnimatedContainer是一个非常强大的隐式动画小部件,因为它有许多影响其外观的属性,并且所有这些属性都是自动插入的。 所有其他隐式动画小部件也是功能强大、易于使用的选项,可以在不增加很多复杂度的情况下添加动画。 此外,您不一定需要将这些小部件放入StatefulWidget并使用setState,您可以使用StreamBuilder和FutureBuilder来触发本例中的动画。

深入研究动画

 隐式动画小部件是您添加动画的首选,然而,这并不是Flutter的动画系统所能提供的全部。在本系列的其余部分中,我们将探讨颤振动画系统的底层,并向您展示如何直接使用动画系统来构建高级动画。