浅解动画

Flutter中的动画系统基于Animation对象的类型。控件可以直接通过读取其当前的值并监听其状态变化来将这些动画添加到其构建函数中,或者可以使用动画作为更精细的动画的基础,并将它们传递给其他控件。

Animation

动画系统的主要构建块是Animation类。动画表示可以在动画生命周期内改变的特定类型的值。执行动画的大多数控件都会接收一个Animation对象作为参数,从中读取动画的当前值,并监听对象对该值的更改。

addListener

每当动画的值更改时,动画通知所有添加了addListener的监听器。通常,监听动画的State对象将在其监听器回调中调用setState,以通过动画的新值向控件系统通知其需要重构。

这种模式是很常见的,当动画更改值时,有两个控件帮助控件重建:AnimatedWidget和AnimatedBuilder。第一个,AnimatedWidget,对于无状态的动画控件最有用。要使用AnimatedWidget,只需将其子类化并实现构建函数即可。第二个,AnimatedBuilder,对于更复杂的控件很有用,可以将动画作为其构建函数的一部分。要使用AnimatedBuilder,只需构建控件并传递一个builder函数。

addStatusListener

动画还提供了一个AnimationStatus,它指示动画随着时间的推移如何演变。每当动画的状态发生变化时,动画通知所有添加了addStatusListener的监听器。通常动画从dismissed状态开始,这意味着它们处于其范围的开始。例如,从0.0到1.0的动画为dismissed时,其值为0.0。然后,动画可以运行forward(比如从0.0到1.0)或者reverse(比如从1.0到0.0)。最终,如果动画达到其范围的最终值(比如1.0),则动画达到completed状态。

AnimationController

要创建动画,首先创建一个AnimationController。除了作为动画本身,AnimationController可以让您控制动画。例如,您可以告诉控制器forward(向前播放)或stop(停止)动画。您还可以fling(投掷)动画,其使用诸如弹簧的物理模拟来驱动动画。

创建动画控制器后,就可以基于它开始构建其他动画。例如,可以创建一个ReverseAnimation,反映原始动画,但反向运行(比如从1.0到0.0)。类似地,还可以创建一个CurvedAnimation,曲线动画,其值由curve调整。

Tween

动画在0.0到1.0的区间,可以使用Tween,它在其begin(开始)和end(结束)值之间进行插值。许多类型具有特定的Tween子类,提供类型特定的插值。例如, ColorTween在颜色之间进行插值,并在矩形之间插入RectTween。您可以通过创建自己的Tween子类并覆盖其lerp函数来定义自己的插值。

补间只是定义了如何在两个值之间插值。要获取动画当前帧的具体值,您还需要一个动画来确定当前状态。将补间动画与动画结合起来有两种方法,获得一个具体的值:

  1. 使用evaluate获取动画当前值的补间。这个方法对于已经在监听动画的控件最为有用,因此每当动画改变值时重建。

  2. 使用animate为补间动画添加动画。而不是返回单个值,animate函数返回一个包含补间的新动画。当您想要将新创建的动画提供给另一个控件时,此方法最为有用,然后可以读取包含补间的当前值以及监听对值的更改。

动画结构

动画实际上是由许多核心构建块构建的。

Scheduler

SchedulerBinding是暴露Flutter调度原语的单例类。

在这个讨论中,关键的原语是帧回调。每当需要在屏幕上显示一个帧时,Flutter的引擎会触发一个“开始帧”回调,调度器将复制到所有使用scheduleFrameCallback()注册的监听器。所有这些回调都是以某个任意时期的Duration(持续时间)的形式给出该帧的官方时间戳。由于所有回调具有相同的时间,所以从这些回调触发的任何动画都将完全同步,即使它们需要几毫秒来执行。

Tickers

Ticker类挂接到调度程序的scheduleFrameCallback()机制中,以便每个刻度调用回调。

Ticker可以启动和停止。启动时,它返回一个将在停止时解决的Future。

每个刻度,Ticker提供回调与开始之后第一个刻度的持续时间。

因为在启动之后,代码总是给予相对于第一个刻度的经过时间,所有的代码都是同步的。如果您在两帧之间的不同时间启动三个刻度,则它们将全部同步于相同的起始时间,并随后将被锁定。

Simulations

Simulation抽象类将相对时间值(经过时间)映射到双精度值,并具有完成的概念。

原则上模拟是无状态的,但在实践中,一些模拟(例如,BouncingScrollSimulation和ClampingScrollSimulation)在查询时不可逆地改变状态。

有简单的一维物理模拟,如弹簧、摩擦和重力等不同效果的Simulation类的各种具体实现。

Animatables

Animatable抽象类将一个双精度值映射到一个特定类型的值

Animatable类是无状态和不可变的。

Tweens

Tween抽象类将在0.0-1.0范围内的双精度值映射到类型值(例如,Color或另一个双精度值),是一个Animatable。

它具有输出类型(T),该类型的begin(起始)值和end(结束)值的概念,以及在给定输入值的起始值和结束值之间插值(lerp)的方式(双精度值范围在0.0-1.0内)。

Tween类是无状态的和不可变的。

链接Animatables

将Animatable(父类)传递给动画的chain()方法会创建一个新的Animatable子类,该子类应用父映射,然后应用子映射。

曲线

Curve抽象类映射在0.0-1.0范围内翻倍,以0.0-1.0的范围翻倍。

Curve类是无状态的和不变的。

Animations

Animation抽象类提供给定类型的值、动画方向和动画状态的概念,以及用于注册在值或状态更改时调用的回调的监听器接口。

Animation的一些子类具有从不改变的值(kAlwaysCompleteAnimation, kAlwaysDismissedAnimation, AlwaysStoppedAnimation);在这些上注册回调没有任何效果,因为从未调用回调。

Animation变体是特别的,因为它可以用于表示一个双精度值的范围0.0-1.0,这是Curve和Tween类预期的输入以及Animation的一些其他子类。

一些Animation子类是无状态的,只是将监听器转发给他们的父类,还有些是有状态的。

可链接动画

大多数Animation子类采用显式的父类Animation。它们由父类驱动。

CurvedAnimation子类将一个Animation类(父类)和一对Curve类(正向和反向曲线)作为输入,并使用父值作为曲线的输入来确定其输出。 CurvedAnimation是不可变的和无状态的。

ReverseAnimation子类将Animation类作为其父类,并反转动画的所有值。它假定父级使用的值在0.0-1.0范围内,并返回1.0-0.0范围内的值。父动画的状态和方向也相反。CurvedAnimation是不可变的和无状态的。

ProxyAnimation子类将Animation类作为其父类,并转发该父类的当前状态。但是父类是可变的。

TrainHoppingAnimation子类需要两个父类,并在它们的值跨越时切换它们。

动画控制器

AnimationController是有状态的Animation,它使用一个Ticker来赋予自己的生命。它可以启动和停止。每个刻度,它需要从它开始的时间经过,并将其传递给Simulation以获得一个值。那就是它报告的值。如果Simulation报告说,当时它已经结束,那么控制器就会自动停止。

动画控制器可以被赋予一个下限和上限的动画之间和持续时间。

在简单的情况下(使用forward(),reverse(),play()和resume()),动画控制器简单地从下限到上限进行线性插值(反之亦然)在给定的持续时间。

当使用repeat()时,动画控制器在给定的持续时间内使用给定范围之间的线性插值,但不会停止。

当使用animateTo()时,动画控制器在给定持续时间内从当前值到给定目标进行线性插值。如果该方法没有持续时间,则使用控制器的默认持续时间和由控制器的下限和上限描述的范围来确定动画的速度。

当使用fling()时,Force用于创建一个特定的simulation,然后用于驱动控制器。

当使用animateWith()时,给定的simulation用于驱动控制器。

这些方法都返回了Ticker提供的future,当控制器下次停止或更改simulation时,这些方法将会解决。

将动画附加到动画

将Animation(新父类)传递给动画的animate()方法将创建一个新的Animation子类,其动作类似于Animatable,但是从给定的父类驱动。

Flutter进阶—解析动画相关推荐

  1. Flutter进阶—实现动画效果(一)

    上一篇文章我们了解了Flutter的动画基础:Flutter进阶-解析动画,这一篇文章我们就来实现一个图表的动画效果. 首先,我们需要创建一个新项目myapp,然后把main.dart的内容替换成下面 ...

  2. Flutter进阶—实现动画效果(四)

    在上一篇文章:Flutter进阶-实现动画效果(三)中,实现了一个随机高度.颜色的条形.这一篇文章我们会实现多个条形,同样是随机高度.颜色. 首先在bar.dart中创建BarChart类,并使用固定 ...

  3. Flutter进阶—实现动画效果(三)

    在上一篇文章:Flutter进阶-实现动画效果(二)的最后,我们实现了一个控件,其中包含各种布局和状态处理控件.以及使用自定义的动画感知绘图代码绘制单个Bar的控件.还有一个浮动按钮控件,用于启动条形 ...

  4. Flutter进阶—实现动画效果(二)

    在上一篇文章:Flutter进阶-实现动画效果(一)的最后,我们说到需要一个处理程序混乱的概念.在这一篇文章中,我们会引入补间,它是构建动画代码的一个非常简单的概念,主要作用是用面向对象的方法替代之前 ...

  5. Flutter进阶—实现动画效果(十)

    前面的两篇文章[动画效果(八).动画效果(九)]中,我们只需要统计产品和地区,如果现在增加一个统计项目--销售渠道,那么使用之前的堆叠条形图和分组条形图都不适合.我们可以将两者结合,使用分组+堆叠条形 ...

  6. Flutter进阶—实现动画效果(八)

    通过学习前面的文章,我们现在终于能为更复杂的图表制作动画效果了[手动斜眼笑].接着上一篇文章讲,如果公司的产品销往全国各地,那么我们的图表要展示的内容就需要加上地区.我们可以使用堆叠条形图来试试效果, ...

  7. Flutter进阶—实现动画效果(六)

    在上一篇文章中,我们之前对BarChart.lerp的定义并不是高效的,我们正在创建的Bar实例,仅作为Bar.lerp的参数给出,并且针对动画参数t的每个值重复出现.每秒60帧,这意味着可能很多Ba ...

  8. Flutter进阶—实现动画效果(五)

    在本篇文章开始前,我们先来回顾一下之前我们都做了哪些事情.在第一篇文章中,我们在动画值更改时调用double lerpDouble(num a, num b, double t)重新绘制条形.在第二篇 ...

  9. Flutter进阶—实现动画效果(九)

    在上一篇文章中,我们实现了统计每个产品和地区的销售额,如果现在需要统计每个产品和地区所占市场份额的百分比,那么使用堆叠条形图是不合适的,我们可以使用分组条形图,因为它可以同时在两个类别维度上进行定量比 ...

最新文章

  1. AI在智能建筑中的应用和发展
  2. 百度搜索效果(页面传来数据地址,由服务器去获取)
  3. 26期Linux20180531 单用户 救援模式 克隆虚拟机 linux机器相互登录
  4. Nginx server_name通配符匹配配置
  5. lan口配置 petalinux_PetaLinux安装及使用
  6. VMWare 安装 Eclipse
  7. Visual Editor插件下载、安装问题(Eclipse3.1.1)
  8. 脚本两则--用于快速部署HADOOP,SPARK这些(特别是VM虚拟机模板部署出来的)。。...
  9. agv系统介绍_AGV地面控制系统介绍
  10. 因代码不规范,码农枪击了4名同事!
  11. flex acionscript png图片去除多余空白,生成合适大小图片
  12. Cocos2d-js cc.director介绍
  13. 淘宝宝贝图片批量下载教程
  14. 数电课程设计——电子钟
  15. 它是最给力的数据分析体系,却被90%的新人忽略!
  16. 授权管理-LDAP-介绍与环境搭建
  17. 美森快船收费标准和操作流程是怎样的?
  18. 我的物联网项目(五)下单渠道
  19. 如何设计安全可靠的开放接口---之AppId、AppSecret
  20. 改变人类进程的,除了霍金,还有他的好基友们

热门文章

  1. Java实验9 T1.往文件中写入1万个随机数,比较用时的多少
  2. Transformer的学习笔记
  3. Python中的文件复制
  4. 带参数的sigmoid
  5. CSS中的偏僻知识点
  6. mac上使用python 安装anaconda和pycharm
  7. 剑指offer——3.实现数组中重复数字查找
  8. ALM产品六爻:TeleLogic, Rational, DevTrack, Jira, RTC, URTrack...
  9. Native层和so接口和Java层
  10. Android Studio开发学习 - 1. 添加Activity