Flutter动画

本文概述

  • 补间动画
  • 基于物理的动画
  • 弯曲动画
  • 英雄动画
动画是Flutter中非常重要的概念。我们无法想象没有动画的任何移动应用程序。当你点击按钮或从一页移动到另一页时, 所有动画都是。动画可以增强用户体验, 并使应用程序更具交互性。
Flutter为动画提供了出色的支持, 可以将动画分为两个主要类别, 如下所示:
  • 补间动画
  • 基于物理的动画
补间动画 【Flutter动画】它是中介的简称。在补间动画中, 需要定义动画的起点和终点。这意味着动画从起始值开始, 然后经过一系列中间值, 最后达到结束值。它还提供了时间线和曲线, 它们定义了转换的时间和速度。小部件框架提供了如何从起点和终点过渡的计算。

ColorTween {begin: color.green, end: color.blue, }

基于物理的动画 这是一种动画类型, 可让你使应用程序交互感觉逼真且互动。它模拟现实世界中的动画/运动, 例如你要为小部件设置动画, 例如弹簧, 下落或因重力而摆动。因此, 它是响应于用户输入/运动而进行动画处理的动画。最简单的例子是飞行时间, 所涵盖的旅行距离将根据物理定律进行计算。
Flutter提供了两种类型的动画技术。这些技术是:
  1. 隐式动画
  2. 显式动画
下图列出了Flutter中的动画层次, 并更清楚地说明了隐式和显式动画。
Flutter动画

文章图片
现在, 我们将看到如何在Flutter中创建显式动画。动画主要有以下三个支柱:
  1. 股票代号
  2. 动画课
  3. 动画控制器
股票代号
股票行情指示器是一种以规则的时间间隔(即每秒约60次)发送信号的类。你可以通过手表来了解它, 并定期抽动。在每次滴答时, 滴答声提供了一种回调方法, 该方法具有自启动后每秒钟第一次滴答开始的持续时间。即使行情自动收录器在不同的时间开始, 它始终会自动同步。这背后的原因是, 行情自动收录器给出了相对于其开始之后的第一个行情的经过时间。
动画
Animation类是动画系统的核心构建块。动画没什么, 但是它表示一个值(特定类型), 该值可以在动画的整个生命周期内变化。在Flutter中, 执行动画的小部件将动画对象作为参数。这个Animation对象提供了从中读取动画当前值以及侦听该值更改的信息。动画类包含两个方法addListener()和addStatusListener()。当animation的值更改时, 它将通知所有使用addListener()添加的侦听器。同样, 当动画的状态更改时, 它会通知所有使用addStatusListener()添加的侦听器。
最常见的动画类是:
  • Animation < double> :在一定的持续时间内, 在两个小数之间插入值。
  • Animation < Color> :在两个颜色值之间插值颜色。
  • Animation < Size> :在两个大小值之间插入大小。
动画控制器
动画控制器是允许我们控制动画的类。每当应用程序准备好新框架时, 它始终会生成新值。例如, 它可以控制动画的开始, 停止, 前进或重复。一旦创建了动画控制器, 我们就可以基于它开始构建其他动画, 例如反向动画和弯曲动画。
animcontroller = AnimationController(vsync: this, duration: Duration(milliseconds: 2500));

在这里, duration选项控制动画过程的持续时间, 而vsync选项用于优化动画中使用的资源。
使用AnimationController的基本步骤如下:
步骤1:首先, 使用诸如duration和vsync之类的参数实例化AnimationController。
步骤2:添加所需的侦听器, 例如addListener()或addStatusListener()。
步骤3:开始动画。
步骤4:在侦听器回调方法(例如setState)中执行操作。
步骤5:最后, 处理动画。
让我们看一个简单的动画示例, 该示例使用动画类和动画控制器。以下示例显示了补间动画, 该补间动画给出了动画的开始和终点。打开项目, 并在main.dart文件中替换以下代码。
import 'package:flutter/animation.dart'; import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget {// This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Animation', theme: ThemeData(// This is the theme of your application.primarySwatch: Colors.blue, ), home: MyHomePage(), ); }}class MyHomePage extends StatefulWidget {_HomePageState createState() => _HomePageState(); }class _HomePageState extends State< MyHomePage> with SingleTickerProviderStateMixin {Animation< double> animation; AnimationController animationController; @overridevoid initState() {super.initState(); animationController = AnimationController(vsync: this, duration: Duration(milliseconds: 2500)); animation = Tween< double> (begin: 0.0, end: 1.0).animate(animationController); animation.addListener((){setState((){print (animation.value.toString()); }); }); animation.addStatusListener((status){if(status == AnimationStatus.completed){animationController.reverse(); } else if(status == AnimationStatus.dismissed) {animationController.forward(); }}); animationController.forward(); }@overrideWidget build(BuildContext context) {return Center(child: AnimatedLogo(animation: animation, )); }}class AnimatedLogo extends AnimatedWidget {final Tween< double> _sizeAnimation = Tween< double> (begin: 0.0, end: 500.0); AnimatedLogo({Key key, Animation animation}):super(key: key, listenable: animation); @overrideWidget build(BuildContext context) {final Animation< double> animation = listenable; return Transform.scale(scale: _sizeAnimation.evaluate(animation), child: FlutterLogo(), ); }}

输出量
在Android Studio中运行该应用程序时, 将获得输出。在屏幕上, 你将看到Flutter徽标正反方向缩放。
Flutter动画

文章图片
弯曲动画 当你需要对动画对象应用非线性曲线时, 弯曲动画非常有用。因此, 它将动画的进度定义为非线性曲线。
句法:
CurvedAnimation(parent: animationController, curve: Curves.bounceOut));

让我们通过前面的示例来理解它。要添加曲线, 请在android studio中打开以前的应用, 然后添加CurvedAnimation而不是animationController。或替换以下行:
animation = Tween< double> (begin: 0.0, end: 1.0).animate(animationController);

与下面的行。
animation = Tween< double> (begin: 0.0, end: 1.0).animate(animationController);

现在, 当你运行该应用程序时, 在向前和向后缩放时, 将看到带有Flutter徽标的弹跳效果。
英雄动画 英雄动画是一种动画, 当应用程序转到下一页时, 其中一个屏幕的元素会飞到新屏幕。我们可以通过以下示例来理解它, 其中动画采用图标/图像之类的元素, 然后在点击图标后, 屏幕将跳至下一页。以下示例对其进行了更清晰的说明。
打开Flutter应用程序, 然后在main.dart文件中替换以下代码。
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget {// This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Application', theme: ThemeData(primarySwatch: Colors.orange, ), home: HeroAnimation(title: 'Hero Animation'), ); }}class HeroAnimation extends StatefulWidget {HeroAnimation({Key key, this.title}) : super(key: key); final String title; @override_HeroAnimationState createState() => _HeroAnimationState(); }class _HeroAnimationState extends State< HeroAnimation> {Widget _greenRectangle() {return Container(width: 75, height: 75, color: Colors.green, ); }Widget _detailPageRectangle() {return Container(width: 150, height: 150, color: Colors.red, ); }@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(widget.title), ), body: buildDemoWidget(context), ); }Widget buildDemoWidget(BuildContext context) {return Center(child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: < Widget> [SizedBox(height: 30.0, ), ListTile(leading: GestureDetector(child: Hero(tag: 'hero-rectangle', child: _greenRectangle(), ), onTap: () => _gotoDetailsPage(context), ), title: Text('Tap on the green icon rectangle to analyse hero animation transition.'), ), ], ), ); }void _gotoDetailsPage(BuildContext context) {Navigator.of(context).push(MaterialPageRoute(builder: (ctx) => Scaffold(body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center, children: < Widget> [Hero(tag: 'hero-rectangle', child: _detailPageRectangle(), ), Text('This is a place where you can see details about the icon tapped at previous page.'), ], ), ), ), )); }}

输出量
在Android Studio中运行该应用程序时, 将显示以下屏幕。
Flutter动画

文章图片
要显示英雄动画, 请点击绿色图标, 它将立即飞到一个新屏幕, 你将在其中获得有关所点击项目的详细信息。
Flutter动画

文章图片

    推荐阅读