Skip to content

Key 和动画

Key 详解

我们平时一定接触过很多的 Widget,比如 Container、Row、Column 等,它们在我们绘制界面的过程中发挥着重要的作用。但是不知道你有没有注意到,在几乎每个 Widget 的构造函数中,都有一个共同的参数,它们通常在参数列表的第一个,那就是 Key。

在Flutter中,Key是不能重复使用的,所以Key一般用来做唯一标识。组件在更新的时候,其状态的保存主要是通过判断组件的类型或者key值是否一致。因此,当各组件的类型不同的时候,类型已经足够用来区分不同的组件了,此时我们可以不必使用key。但是如果同时存在多个同一类型的控件的时候,此时类型已经无法作为区分的条件了,我们就需要使用到key。

LocalKey、GlobalKey

LocalKey、GlobalKeyFlutter key 子类包含 LocalKey 和 GlobalKey

  • 局部键(LocalKey):ValueKey、ObjectKey、UniqueKey
  • 全局键(GlobalKey): GlobalKey、GlobalObjectKey

ValueKey (值 key)把一个值作为 key ,UniqueKey(唯一 key)程序生成唯一的 Key,当我们不知道如何指定 ValueKey 的时候就可以使用 UniqueKey,ObjectKey(对象 key)把一个对象实例作为 key。

GlobalKey(全局 key),GlobalObjectKey(全局 Objec key,和 ObjectKey 有点类似)

GlobalKey的使用

如果把LocalKey比作局部变量, GlobalKey就类似于全局变量下面使用了LocalKey,当屏幕状态改变的时候把 Colum换成了Row,Box的状态就会丢失.

获取子组件状态

  • globalKey.currentState 可以获取子组件的状态,执行子组件的方法
  • globalKey.currentWidget 可以获取子组件的属
  • _globalKey.currentContext!.findRenderobject()可以获取渲染的属性。

Widget Tree、Element Tree 和 RenderObject Tree

Flutter应用是由是Widget Tree、Element Tree 和 RenderObject Tree组成Widget可以理解成一个类,Element可以理解成Widget的实例,Widget与Element的关系可以是一对多,一份配置可以创造多个Element实例

属性描述
WidgetWidget就是一个类, 是Element 的配置信息。与Element的关系可以是一对多,一份配置可以创造多个Element实例
ElementWidget 的实例化,内部持有Widget和RenderObject。
RenderObject负责渲染绘制

默认情况下面,当Flutter同一个 Widget的大小,顺序变化的时候,FLutter不会改变Widget的state。

Flutter 动画

动画原理

动画基本原理以及 Flutter 动画简介

在任何系统的 UI 框架中,动画实现的原理都是相同的,即:在一段时间内,快速地多次改变 UI 外观;由于人眼会产生视觉暂留,所以最终看到的就是一个“连续”的动画,这和电影的原理是一样的。我们将 UI 的一次改变称为一个动画帧,对应一次屏幕刷新,而决定动画流畅度的一个重要指标就是帧率 FPS(Frame Per Second),即每秒的动画帧数。很明显,帧率越高则动画就会越流畅!一般情况下,对于人眼来说,动画帧率超过 16 FPS,就基本能看了,超过 32 FPS 就会感觉相对平滑,而超过 32 FPS,大多数人基本上就感受不到差别了。由于动画的每一帧都是要改变 UI 输出,所以在一个时间段内连续的改变 UI 输出是比较耗资源的,对设备的软硬件系统要求都较高,所以在 UI 系统中,动画的平均帧率是重要的性能指标,而在 Flutter 中,理想情况下是可以实现 60FPS 的,这和原生应用能达到的帧率是基本是持平的。

Flutter 动画简介

FLutter 中的动画主要分为:隐式动画、显式动画、自定义隐式动画、自定义显式动画、和 Hero 动画

隐式动画

通过几行代码就可以实现隐式动画,由于隐式动画背后的实现原理和繁琐的操作细节都被隐去了,所以叫隐式动画,FLutter 中提供的 AnimatedContainer、AnimatedPadding、AnimatedPositioned、 AnimatedOpacity、AnimatedDefaultTextStyle、AnimatedSwitcher 都属于隐式动画。隐式动画中可以通过 duration 配置动画时长、可以通过 Curve (曲线)来配置动画过程

AnimatedContainer

AnimatedContainer 的属性和 Container 属性基本是一样的,当 AnimatedContainer 属性改变的时候就会触发动画

AnimatedPadding 以及 curve 属性

Curves 曲线值

曲线名动画过程
linear匀速的
decelerate匀减速
ease开始加速,后面减速
easeIn开始慢,后面快
easeOut开始快,后面慢
easeInOut开始慢,然后加速,最后再减速
更多曲线https://docs.flutter.io/flutter/animation/Curves-class.html 官方文档打不开也可以参考教程目录中提供的 gif 截图

AnimatedPositioned

AnimatedOpacity

AnimatedDefaultTextStyle