写点什么

Flutter 动画【Flutter 专题 16】

作者:坚果前端
  • 2021 年 12 月 07 日
  • 本文字数:4090 字

    阅读完需:约 13 分钟

Flutter 动画【Flutter专题16】

动画是 Flutter 中一个非常强大和重要的概念。我们无法想象没有动画的任何移动应用程序。当您点击一个按钮或从一个页面移动到另一个页面时,都是动画。动画增强了用户体验并使应用程序更具交互性。

如果要使用插件,可以看我 的Flutter 的动画包【Flutter 专题 4】


flutter 对动画提供了很好的支持,可以将动画分为两大类,分别如下:


  • 补间动画

  • 基于物理的动画

补间动画

它是 in-betweening 的缩写形式。在补间动画中,需要定义动画的起点终点。这意味着动画从开始值开始,然后经过一系列中间值,最后到达结束值。它还提供时间线和曲线,用于定义过渡的时间和速度。小部件框架提供了如何从起点和终点过渡的计算。


ColorTween {      begin: color.green,      end: color.blue,  }  
复制代码

基于物理的动画

它是一种动画类型,可让您使应用程序交互感觉逼真且具有交互性。它模拟现实世界的动画/运动,例如您想要为小部件制作动画,如弹簧、下落或重力摆动。因此,它是一种响应用户输入/移动而产生动画的动画。最简单的例子是飞行时间,飞行距离会根据物理定律计算。


Flutter 提供了两种类型的动画技术。这些技术是:


  1. 隐式动画

  2. 显式动画


下图列出了 Flutter 中的动画层次结构,并更清楚地解释了隐式和显式动画。



现在,我们将详细的了解如何在 Flutter 中创建显式动画。动画主要有三大支柱,分别如下:


  1. Ticker

  2. 动画类

  3. 动画控制器

Ticker

Ticker 是一种以固定间隔(即每秒 60 次左右)发送信号的类。您可以通过手表了解它,它会定期抽动。在每个滴答声中,Ticker 提供了一个回调方法,其中包含自启动后每秒第一个滴答声以来的持续时间。即使代码在不同的时间开始,它也总是自动同步。这背后的原因是 Ticker 给出了它们相对于开始后的第一个滴答声的经过时间。

动画

Animation 类是动画系统的核心构建块。动画不是别的,但它代表一个值(特定类型),可以在动画的生命周期内改变。在 Flutter 中,执行动画的小部件将动画对象作为参数。这个 Animation 对象提供信息,他们从中读取动画的当前值,并监听该值的变化。动画类包含两个方法 addListener()addStatusListener()。当动画的值发生变化时,它会通知所有使用 addListener() 添加的侦听器。同样,当动画的状态发生变化时,它会通知所有使用 addStatusListener() 添加的侦听器。


最常见的动画类是:


  • **Animation<double>:**它在一定时间内在两个十进制数之间插入值。

  • **Animation<Color>:**它在两个颜色值之间插入颜色。

  • **Animation<Size>:**它在两个尺寸值之间插入尺寸。

动画控制器

动画控制器是一个允许我们控制动画的类。每当应用程序准备好接收新帧时,它总是会生成新值。例如,它可以控制动画的开始、停止、前进或重复。创建动画控制器后,我们可以开始基于它构建其他动画,例如反向动画和曲线动画。


animcontroller = AnimationController(vsync: this, duration: Duration(milliseconds: 2500));  
复制代码


这里,duration 选项控制动画过程的持续时间,vsync 选项用于优化动画中使用的资源。


使用 AnimationController 所需的基本步骤是:


**第一步:**首先,实例化一个 AnimationController,带参数,比如 duration 和 vsync。


**第 2 步:**添加所需的侦听器,如 addListener() 或 addStatusListener()。


**第 3 步:**开始动画。


**第四步:**执行监听回调方法中的动作(例如 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. @override Widget 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 { late Animation<double> animation; late AnimationController animationController; @override void 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(); } @override Widget 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, required Animation animation}):super(key: key, listenable: animation); @override Widget build(BuildContext context) { final Animation<double> animation = listenable as Animation<double>; return Transform.scale( scale: _sizeAnimation.evaluate(animation), child: FlutterLogo(), ); }}
复制代码


当您在 Android Studio 中运行应用程序时,您将获得输出。在屏幕中,您将看到 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 徽标的弹跳效果

Hero 动画

Hero 动画是一种动画类型,当应用程序转到下一页时,一个屏幕的元素会飞到新屏幕。我们可以通过以下示例来理解它,其中动画采用图标/图像等元素,一旦您点击图标,屏幕就会飞到下一页。下面的例子更清楚地解释了它。


打开 Flutter 应用并替换 main.dart 文件中的以下代码。


import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget 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, ); }
@override Widget 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.'), ], ), ), ), )); }}
复制代码


要显示 Hero 动画,请点击绿色图标,它会立即飞到一个新屏幕,您将在其中获得有关被点击项目的详细信息。

发布于: 2 小时前阅读数: 11
用户头像

坚果前端

关注

此间若无火炬,我便是唯一的光 2020.10.25 加入

公众号:“坚果前端”,华为云享专家,51CTO博客首席体验官,专注于大前端技术的分享,包括Flutter,小程序,安卓,VUE,JavaScript。

评论

发布
暂无评论
Flutter 动画【Flutter专题16】