IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Flutter Key的原理和使用(三) LocalKey的三种类型 -> 正文阅读

[移动开发]Flutter Key的原理和使用(三) LocalKey的三种类型

Flutter Key的原理和使用(一) 没有Key会发生什么

Flutter Key的原理和使用 (二) Widget 和 Element 的对应关系

Flutter Key的原理和使用(三) LocalKey的三种类型

我们在上一章说到,同一级中相同类型的Widget不给它传Key的话,Flutter有时候就会出现分不清它们之间的对应关系,尤其是Widget之间的顺序发生改变的时候. 此时,我们就需要传个key给它.

Key的种类

Key有两个子类:

  • LocalKey 局部键,在同一级中要唯一,可以理解为同级唯一性
  • GlobalKey 全局键 , 在整个App中必须是唯一的.

从性能上来讲,如果不需要用到GlobalKey的话,尽量不用,LocalKey因为只对比同一级别,因此会快很多.上一章也说过,在父级或者子级是不会需考虑的.
如果违背了上述的唯一性原则,运行时会报错,提示你Key没有只出现一次.

LocalKey

而LocalKey又有3个子类

  • ValueKey
  • ObjectKey
  • UniqueKey

其实当你的Widget全都是StatelessWidget的时候,不需要用到Key,只有当使用Statefuldiget的时候才有可能用到key.

ValueKey

const ValueKey(this.value)

final T value;

@override
bool operator ==(Object other) {
  if (other.runtimeType != runtimeType)
    return false;
  return other is ValueKey<T>
      && other.value == value;
}

它的构造方法很简单,有一个value,类型是T,也就是随便你想传什么都可以.当然因为唯一性原则,同级中Valukey的value是不能相同的.这个可以看它的operator方法.

ObjectKey

const ObjectKey(this.value);

final Object? value;

@override
bool operator ==(Object other) {
  if (other.runtimeType != runtimeType)
    return false;
  return other is ObjectKey
      && identical(other.value, value);
}

ObjectKey跟ValueKey大同小异,我们主要看一下区别,value的类型从T变成了Object,operator方法也不一样.
identical对比是否是相等或者说相同的时候,它其实属于对比引用或者说指针是否相等,类似于Java中对比内存地址.

我们创建一个稍微复杂一点的类看一下二者实际的区别:

class People{
  final String name;
  final int age;

  People(this.name, this.age);

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is People && runtimeType == other.runtimeType && name == other.name && age == other.age;

  @override
  int get hashCode => name.hashCode ^ age.hashCode;
}

主要看一下operator方法,当年龄相等并且姓名相等时,就判断是相等的.
此时如果代码是这样的话:

Box(Colors.red, key: ValueKey(People('a', 18))),
Box(Colors.red, key: ValueKey(People('a', 18))),

运行之后,

image.png

啊,果不其然,报错了.
然后我们换成ObjectKey试试:

11123123.gif

这就是因为People('a', 18)是new出来的新对象(在dart中,new关键字是可以被省略的),flutter判断二者不是同一个对象,因为对应的ObjectKey也不相等.
这就是ObjectKey跟ValueKey的主要区别.

UniqueKey

class UniqueKey extends LocalKey {
  UniqueKey();

  @override
  String toString() => '[#${shortHash(this)}]';
}

顾名思义,UniqueKey是一个独一无二的Key,也就是说它只和自己相等.因此UniqueKey()UniqueKey()是不相等的.

aas.gif
可以看到,换成UniqueKey之后,再进行hot reload,发现状态丢失了,因为Key变了, 新的UniqueKey和旧的是不相等的.所以state就没有办法保留下来.

那么问题来了, 这玩意到底有啥用?

其实,丢失状态就是它的一种用法,一般在动画效果中会用到.
另外就是它不需要value,当你不想传个value的时候,像我经常有起名头疼的毛病,需要key的时候,这个value该传什么值, 我得想一会,可能还想不好,索性不传了,此时可以使用UniqueKey.

那就又有个问题,它每次都会丢掉状态啊,不是我们希望的,怎么办?

把UniqueKey定义到build的外部,比如

final keyRed = UniqueKey();
final keyBlue = UniqueKey();

因为是一开始就new出来的两个Key,所以在使用的时候,keyRed是没有改变的,也就达到了我们的目的.

GlobalKey

ok,接下来说到GlobalKey , 因为标题的原因啊,我们下一章再讲它.

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-09-04 17:39:38  更:2021-09-04 17:39:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 13:21:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码