概述
Flutter Key的原理和使用(一) 没有Key会发生什么
Flutter Key的原理和使用(二) Widget 和 Element 的对应关系
Flutter Key的原理和使用(三) LocalKey的三种类型
Flutter Key的原理和使用(四) GlobalKey 的用法
Flutter Key的原理和使用(五) 需要key的实例:可拖动改变顺序的Listview
我们在上一章说到,同一级中相同类型的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))),
运行之后,
啊,果不其然,报错了.
然后我们换成ObjectKey试试:
这就是因为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()
是不相等的.
可以看到,换成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 , 因为标题的原因啊,我们下一章再讲它.
最后
以上就是含蓄发箍为你收集整理的Flutter Key的原理和使用(三) LocalKey的三种类型的全部内容,希望文章能够帮你解决Flutter Key的原理和使用(三) LocalKey的三种类型所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复