Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >手把手教你用Flutter做炫酷动画

手把手教你用Flutter做炫酷动画

作者头像
IT阅读排行榜
发布于 2019-12-10 07:43:10
发布于 2019-12-10 07:43:10
1.9K00
代码可运行
举报
文章被收录于专栏:华章科技华章科技
运行总次数:0
代码可运行

导读:随着技术的发展,很多网页开发技术都带有动画效果,比如淡入淡出、渐变、变大变小,等等。Flutter中的动画效果可以用酷炫来形容,这也是Flutter的一大特色。现代的应用程序不仅仅需要程序稳定、好用,还需要好看,体验好。那么动画效果是必不可少的。

作者:亢少军

来源:大数据DT(ID:bigdatadt)

01 动画概念

动画顾名思义,就是动起来的画面。如果一直持续的动再加上音频那就是我们平时看的电影了。那么画面为什么会动起来了呢?在回答这个问题之前,我们先引入一个概念。

人眼在观察景物时,光信号传入大脑神经,需经过一段短暂的时间,光的作用结束后,视觉形象并不立即消失,这种残留的视觉称“后像”,视觉的这一现象则被称为“视觉暂留”。

视觉暂留被认为是电影的最重要的一个理论基础。我们看到的动画,实际上是一连串的画面组成,只不过是以很快的速度去播放,人眼在下一个画面出来之前,还残留着上一个画面的视觉,看起来就像是在没有间隔的播放这一系列的图片,也就是我们称之为的动画。

1. 帧与FPS

帧就是影像动画中最小单位的单幅影像画面,一帧就是一副静止的画面。比如我们看到的电影胶片中的每一格即为一帧,电影通常为24帧。

帧又分为关键帧和过渡帧,如下所示:

  • 关键帧:相当于二维动画中的原画,指角色或者物体运动或变化中的关键动作所处的那一帧。
  • 过渡帧:关键帧与关键帧之间的动画可以由软件来创建,叫做过渡帧或者中间帧。

FPS(Frame Per Second),即每秒显示帧的数量。电影每秒播放24帧,即帧率为24FPS。帧率越大则显示的画面越流畅,动画及视频是同一个原理。

2. 插值器/估值器

为了使得动画呈现出丰富的动画效果,就需要使用非线性动画,插值器与估值器可以解决这个问题。概念如下所示:

  • 插值器:设置属性值从初始值过渡到结束值的变化规律,如匀速、加速及减速等等。即确定了动画效果变化的模式,如匀速变化、加速变化等等。主要应用于实现非线性运动的动画效果。
  • 估值器:设置属性值从初始值过渡到结束值的变化具体数值。估值器的作用是协助插值器实现非线性运动的动画效果。

插值器决定值的变化规律(匀速、加速),即决定的是变化趋势,而接下来的具体变化数值则交给估值器。

如:动画进行了50%(初始值=100,结束值=200 ),那么匀速插值器计算出了当前属性值改变的百分比是50%,那么估值器则负责计算当前属性值 = 100 + (200-100)x50% = 150。

插值器其实并不复杂,就是一个数学函数,设置属性值从初始值过渡到结束值的变化规律。每个平台都有自己定义好的一系列插值器,可以供开发者选择使用,也提供自定义的接口,本质上是一个贝塞尔函数

3. Flutter中的动画类型

Flutter中动画分为两类,如下所示:

  • 补间(Tween)动画:定义开始点、结束点、时间和速度等参数,然后由框架自动计算如何从开始点过度达到结束点。
  • 基于物理的动画:模拟真实世界的行为。例如,当你掷球时,球在何处落地,取决于抛球速度有多快、球有多重、距离地面有多远。

02 Flutter的动画相关类

首先来看下Flutter的动画基础概念和相关类,如下所示:

  • Animation:Flutter中动画的核心类
  • AnimationController:动画管理类
  • CurvedAnimation:用于定义非线性曲线动画
  • Tween:补间对象,用于计算动画使用的数据范围之间的插值。
  • Listeners和StatusListeners:用于监听动画状态改变

1. Animation介绍

Flutter中的动画核心类,我们可以理解为Animation是Flutter中动画的基类。它是个抽象类(abstract),所以不能够直接创建其对象来使用动画。Animation具有以下特性:

  • Animation对象知道动画的当前状态(例如,它是开始、停止还是向前或向后移动),但它不知道屏幕上显示的内容。
  • Flutter中的Animation对象是一个在一段时间内依次生成一个区间之间值的类。Animation对象的输出可以是线性的、曲线的、一个步进函数或者任何其他可以设计的映射。根据Animation对象的控制方式,动画可以反向运行,甚至可以在中间切换方向。
  • Animation还可以生成除double之外的其他类型值,如:Animation<Color> 或 Animation<Size>。
  • Animation对象有状态,可以通过访问其value属性获取动画的当前值。
  • Animation对象本身和UI渲染没有任何关系。

2. AnimationController动画管理类

AnimationController是一个特殊的Animation对象。其继承自Animation ,因此可以在需要Animation对象的任何地方使用它。默认情况下,AnimationController在给定的持续时间内线性生成从0.0到1.0的值。AnimationController在不使用的时候需要dispose,否则会造成资源的泄漏。AnimationController对象创建如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 AnimationController controller = AnimationController(
      duration: const Duration(milliseconds: 2000),
      vsync: this);

上述是AnimationController 对象的创建方式,构造函数第一个参数是动画执行的时间,单位是毫秒。第二个vsync传入是防止动画离屏之后继续消耗资源。

vsync对象会绑定动画的定时器到一个可视的Widget,所以当Widget不显示时,动画定时器将会暂停,当Widget再次显示时,动画定时器重新恢复执行,这样就可以避免动画相关UI不在当前屏幕时消耗资源。如果要使用自定义的State对象作为vsync时,请包含TickerProviderStateMixin,代码结构大致如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class MyApp extends StatefulWidget {
  _AnimationApp createState() => _AnimationApp();
}

class _AnimationApp extends State<MyApp> with SingleTickerProviderStateMixin {
    //动画实现
}

这里需要提一下TickerProvider类,它的主要作用是获取每一帧刷新的通知,作用相当于给动画添加了一个动起来的引擎。

AnimationController 提供了几个常用的方法。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!--开始动画,从开始值向结束值-->
TickerFuture forward({ double from }) {}

<!--开始反向运行此动画-->
TickerFuture reverse({ double from }) {}

<!--开始执行动画,结束后重新启动-->
TickerFuture repeat({ double min, double max, Duration period }) {}

<!--使用阻尼效果驱动动画-->
TickerFuture fling({ double velocity: 1.0 }) {}

<!--停止动画-->
void stop({ bool canceled: true }) {}

<!--释放此对象使用的资源,此方法调用后不再控制器对象不再可用-->
void dispose() {}

3. CurvedAnimation非线性动画

CurvedAnimation继承Animation,它将动画过程定义为一个非线性曲线,属于Animation<double>类型。构建其对象的方式如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CurvedAnimation curve = CurvedAnimation(parent: controller, curve: Curves.easeIn);

构造函数中传入控制器和要执行的曲线方式。Curves类定义了许多常用的曲线,也可以创建自己的,例如我们使用数学函数Math.sin方法构建一个抖动的曲线,代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class ShakeCurve extends Curve {
  @override
  double transform(double t) {
    return math.sin(t * math.PI * 2);
  }
}

Flutter定义了一系列的插值器,封装在Curves类中,有下面13种效果:

  • linear
  • decelerate
  • ease
  • easeIn
  • easeOut
  • easeInOut
  • fastOutSlowIn
  • bounceIn
  • bounceOut
  • bounceInOut
  • elasticIn
  • elasticOut
  • elasticInOut

4. Tween补间值生成类

AnimationController对象的范围为0.0到1.0。如果需要不同的范围或不同的数据类型,可以使用Tween将动画配置为插入到不同的范围或数据类型。例如,以下Tween从0.0变为500.0:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Tween doubleTween = Tween<double>(begin: 0.0, end: 500.0);

构造函数传入只需要传入begin和end两个值,当然这里不一定只是double值。

Tween继承自Animatable<T>,而不是继承自Animation<T>。Animatable与Animation相似,不是必须输出double值。例如,ColorTween指定两种颜色之间的过渡。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
final Tween colorTween =
ColorTween(begin: Colors.transparent, end: Colors.black54);

要使用Tween对象,请调用其animate()方法,传入一个控制器对象。例如,以下代码在100毫秒内生成从0到200的整数值。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
final AnimationController controller = AnimationController(
    duration: const Duration(milliseconds: 100), vsync: this);
Animation<int> alpha = IntTween(begin: 0, end: 200).animate(controller);

注意:animate()返回的是一个Animation,而不是一个Animatable。

Flutter通过抽象类Animatable来实现估值器。Animatable可以根据不同的输入,产出不同的数值。通过重载下面的函数来产生不同的估值器。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
T transform(double t);

它的最主要的子类是Tween,一个线性的估值器,实现如下,非常的简单,就是一个线性函数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
T lerp(double t) {
  assert(begin != null);
  assert(end != null);
  //返回值 = 开始值 + (结束值 - 开始值) * 传入值
  return begin + (end - begin) * t;
}

@override
T transform(double t) {
  //开始
  if (t == 0.0)
    return begin;
  //结束
  if (t == 1.0)
    return end;
  //中间值  
  return lerp(t);
}

在Tween的基础上实现了不同类型的估值器,如下所示:

  • ReverseTween
  • ColorTween
  • SizeTween
  • RectTween
  • IntTween
  • StepTween
  • ConstantTween

5. Listeners和StatusListeners动画监听

Animation对象可以有Listeners和StatusListeners,用addListener来进行动画监听和addStatusListener进行动画状态添加监听。只要动画的值发生变化,就会调用监听器。我们通常可用调用setState以将动画重置状态。动画开始,结束,前进或后退时调用StatusListener,下列是Flutter提供动画的监听方法。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!--动画添加监听-->
void addListener(VoidCallback listener);

<!--动画移除监听-->
void removeListener(VoidCallback listener);

<!--动画状态添加监听-->
void addStatusListener(AnimationStatusListener listener);

<!--动画状态移除监听-->  
void removeStatusListener(AnimationStatusListener listener);

动画状态如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!--动画状态-->
enum AnimationStatus {

  <!--动画在开始时停止-->   
  dismissed,

  <!--动画从开始状态执行到结束状态-->
  forward,

 <!--动画反向执行,从结束状态执行到开始状态-->
  reverse,

 <!--动画执行完成-->
  completed,

}

6. 动画控制流程

当我们理解了插值器(Curve)、估值器(Tween)以及Ticker回调的原理。我们就可以理出AnimationController大致的工作流程。

随着时间的流逝,插值器根据时间产生的值作为输入,提供给估值器,产生动画的实际效果值,结合Ticker的回调,渲染出当前动画值的图像。这也是补间动画的工作原理。如下图所示。

▲动画控制流程图

关于作者:亢少军,资深开发者,创业者。专注于视频通讯技术领域。国内首本Flutter著作《Flutter技术入门与实战》作者。多年从事视频会议、远程教育等技术研发,对于AndroidiOS以及跨平台开发技术有比较深入的研究和应用,作为主要程序员开发了多个应用项目,涉及医疗、交通、银行等领域。

延伸阅读《Flutter技术入门与实战》第2版

点击上图了解及购买

转载请联系微信:DoctorData

推荐语:本书是多位人工智能技术专家和大数据技术专家多年工作经验的结晶,从工具使用、技术原理、算法设计、案例实现等多个维度对深度学习进行了系统的讲解。内容选择上,广泛涉猎、重点突出、注重实战;内容安排上,实例切入、由浅入深、循序渐进;表达形式上,深度抽象、化繁为简、用图说话。

  • 图书同步配套视频: https://flutter.ke.qq.com
  • Flutter开源项目请关注: https://github.com/kangshaojun
  • Flutter交流学习群:894109159
  • 作者QQ:283796665 微信:kangshaojun888

「大数据」内容合伙人之「鉴书小分队」上线啦!

最近,你都在读什么书?有哪些心得体会想要跟大家分享?

数据叔最近搞了个大事——联合优质图书出版商机械工业出版社华章公司发起鉴书活动。

简单说就是:你可以免费读新书,你可以免费读新书的同时,顺手码一篇读书笔记就行。详情请在大数据公众号后台对话框回复合伙人查看。

有话要说?

Q: Flutter还有哪些炫酷应用?

欢迎留言与大家分享

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-12-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大数据DT 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
FlutterComponent最佳实践之动画那些词儿
什么是动画,从数学上来说,动画指的是一个属性的变换过程,实际上,就是一个函数,将一个属性值变成另一个属性值的过程。
用户1907613
2022/05/17
4590
FlutterComponent最佳实践之动画那些词儿
带你轻松掌握Flutter 动画开发核心技能
在这篇文章中,将向大家分享Flutter动画开发的一些核心技能,以及一些技巧和经验。
CrazyCodeBoy
2019/12/10
7100
带你轻松掌握Flutter 动画开发核心技能
《Flutter》-- 8.动画
不管是什么视图框架,动画的实现原理都是相同的,即在一段时限的时间内,多次、快速地改变视图外观来实现连续播放的效果。
爱学习的程序媛
2022/04/07
1.2K0
《Flutter》-- 8.动画
Flutter | 动画
在任何系统的 UI 框架中,动画的实现原理都是相同的,即:在一段时间内,快速地多次改变 UI 外观;由于人眼会产生视觉停留,所以最终看到的就是一个连续的动画;
345
2022/02/11
1.7K0
Flutter | 动画
Flutter开发·Flutter中动画的实现与使用
Flutter中动画的核心类库是Animation,它并不是一个widget,Animation是一个抽象类,就相当于一个定时器,用来描述当前动画的开始,暂停,以及数值状态,与ui渲染没有任何关系,它不能直接控制ui页面上的组件的样式,组件只能通过获取它的状态来改变ui的状态。
玖柒的小窝
2021/10/07
1.7K0
【Flutter】Animation 动画 ( Flutter 动画的核心类 | Animation | CurvedAnimation | AnimationController | Tween )
Animation : Flutter 动画最核心的类 , 用于生成动画的中间过渡值 ;
韩曙亮
2023/03/29
7740
Flutter | 通过一个小例子带你认识动画 Animation
首先,我们知道在我们的APP中充斥着各种各样的动画,有的是用 GIF,有的用的 Flare,有的是用的 Lottie...。
Flutter笔记
2019/08/29
1.5K0
Flutter | 通过一个小例子带你认识动画 Animation
Flutter 小技巧之有趣的动画技巧
本篇分享一个简单轻松的内容: 剖析 Flutter 里的动画技巧 ,首先我们看下图效果,如果要实现下面的动画切换效果,你会想到如何实现?
GSYTech
2022/06/20
5500
【Flutter实战】动画核心(1/2)
任何程序的动画原理都是一样的,即:视觉暂留,视觉暂留又叫视觉暂停,人眼在观察景物时,光信号传入大脑神经,需经过一段短暂的时间,光的作用结束后,视觉形象并不立即消失,这种残留的视觉称“后像”,视觉的这一现象则被称为“视觉暂留”。
老孟Flutter
2020/09/11
6130
【Flutter实战】动画核心(1/2)
《Flutter 动画系列一》25种动画组件超全总结
任何程序的动画原理都是一样的,即:视觉暂留,视觉暂留又叫视觉暂停,人眼在观察景物时,光信号传入大脑神经,需经过一段短暂的时间,光的作用结束后,视觉形象并不立即消失,这种残留的视觉称“后像”,视觉的这一现象则被称为“视觉暂留”。
老孟Flutter
2020/04/02
1.2K0
Flutter动画【1】
在前面的文章中我们花了很多的时间去讲了Flutter中的Widget以及用户操作,但是我们却很少去关注与用户的交互效果,当然这并不会导致我们的程序崩溃或者不能实现某个功能,但是它真的会使我们应用程序没有“灵性”,总让人觉得少了些什么,对啊,动画!
flyou
2019/08/06
8430
Flutter动画【1】
Flutter 入门指北之手势处理和动画
在前面的一些例子中,小伙伴应该看到了好几次 InkWell 这个部件,通过它我们可以实现对一些手势的监听,并实现 MD 的水波纹效果,举个简单的一个例子
陈宇明
2020/12/16
1.9K0
Flutter 动画之 Animation
1.前言 1.1:Flutter动画中: 首先要看的是Flutter中动画的几个类之间的关系: 主角当然是我们的Animation类了,它可以借助Animatable进行强化 Animata
张风捷特烈
2020/04/30
2.1K0
Flutter 动画之 Animation
《Flutter 动画系列》组合动画
老孟导读:在项目中动画效果很多时候是几种动画的组合,比如颜色、大小、位移等属性同时变化或者顺序变化,这篇文章讲解如何实现组合动画。
老孟Flutter
2020/09/11
1.3K0
【Flutter 实战】动画序列、共享动画、路由动画
Flutter中组合动画使用Interval,Interval继承自Curve,用法如下:
老孟Flutter
2020/09/11
2K0
【Flutter 实战】动画序列、共享动画、路由动画
【Flutter 专题】37 Animation 基本动画 (一)
和尚一直对动画不太熟悉,最近学习了一些关于动画的皮毛知识,网上资料很多,和尚按自己的理解整理一下。
阿策小和尚
2019/08/12
1K0
【Flutter 专题】37 Animation 基本动画 (一)
Flutter跨平台移动端开发丨Animation、AnimationController、Curve
目录 动画相关主要对象 缩放动画 非线性缩放动画 淡入淡出 非线性淡入淡出 平移动画 非线性平移动画 ---- 动画相关主要对象 Animation:可分为线性动画、非线性动画、步进函数动画或其它动画。通过 addListener 方法可以添加监听器,每当动画帧发生改变时均会调用,一般会配合 setState 方法用作UI重建。通过 addStatusListener 方法可添加状态改变监听器,如:动画开始、动画结束等 AnimationController:动画控制器,动画的开始、结束、停止、反向均由
码脑
2019/05/25
1.2K0
【Flutter实战】动画核心(2/2)
动画中还有一个重要的概念就是 Curve,即动画执行曲线。Curve 的作用和 Android 中的 Interpolator(差值器)是一样的,负责控制动画变化的速率,通俗地讲就是使动画的效果能够以匀速、加速、减速、抛物线等各种速率变化。
老孟Flutter
2020/09/11
6880
【Flutter实战】动画核心(2/2)
flutter系列之:如何自定义动画路由
flutter中有默认的Route组件,叫做MaterialPageRoute,一般情况下我们在flutter中进行跳转的话,只需要向Navigator中传入一个MaterialPageRoute就可以了。
程序那些事
2023/04/19
7920
【Flutter 专题】38 Animation 基本动画 (二)
和尚前两天学习了以下 Animation 的基本动画,接下来和尚学习以下稍微进阶版的 Animation 动画。
阿策小和尚
2019/08/12
7090
【Flutter 专题】38 Animation 基本动画 (二)
推荐阅读
相关推荐
FlutterComponent最佳实践之动画那些词儿
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验