21*:Flutter之Key:ValueKey、ObjectKey、UniqueKey、GlobalKey
问题
目录
预备
正文
1:Key 是什么?
用官方的说法就是:
key
是用来作为Widget
、Element
和SemanticsNode
的标示,仅仅用来更新widget->key
相同的小部件的状态。
Key
子类包含LocalKey
和GlobalKey
。
2:LocalKey
看下LocalKey
的定义:
abstract class LocalKey extends Key { const LocalKey() : super.empty(); }
LocalKey
定义了初始化函数,默认为值空。
LocalKey
子类包含ValueKey、
ObjectKey、
UniqueKey
3:ValueKey
ValueKey
顾名思义是比较的是值
看下关键函数
@override bool operator ==(Object other) { if (other.runtimeType != runtimeType) return false; return other is ValueKey<T> && other.value == value; }
那么使用起来也是很简单的,当我们想要系统根据我们所给的key
来判断是否可以刷新时,可以使用该key
TextField( key: ValueKey('value1'), ),
TextField( key: ValueKey('value2'), ),
4:ObjectKey
顾名思义是比较对象的key
,那么这个key
是如何比较对象呢?我们看下源码;
@override bool operator ==(Object other) { if (other.runtimeType != runtimeType) return false; return other is ObjectKey && identical(other.value, value); }
官方显示比较类型,当类型不一致,判定为不是通过一个对象,如果另外一个也是ObjectKey
,则判断地址是否相同,只有地址相同才判定为同一个对象。
测试数据;
class Student { final String name; Student(this.name); @override int get hashCode => name.hashCode; @override bool operator ==(Object other) => identical(this, other) || other is Student && runtimeType == other.runtimeType && name == other.name; } TextField( key: ObjectKey(Student('老王')), ), TextField( key: ObjectKey(Student('老王')), ),
5:UniqueKey
每次生成不同的值,当我们每次刷新都需要一个新的值,那么正是这个存在的意义。
我们每次刷新就生成一个新的 颜色,并且渐隐渐显效果。
AnimatedSwitcher( duration: Duration(milliseconds: 1000), child: Container( key: UniqueKey(), height: 100, width: 100, color: Colors.primaries[count % Colors.primaries.length], ), )
效果:
6:GlobalKey & GlobalObjectKey
作为全局使用的key
,当跨小部件我们通常可以使用GlobalKey
来刷新其他小部件。
GlobalObjectKey
和ObjectKey
是否相等的判定条件是一致的,GlobalObjectKey
继承GlobalKey
,通过GlobalKey<T extends State<StatefulWidget>>
来指定继承state
,并实现StatefulWidget
接口的类,然后可以通过GlobalKey.currentState
来获取当前state
,然后调用state.setState((){})
完成当前小部件标记为dirty
,在下一帧刷新当前小部件。
例子
点击按钮刷新小部件的背景颜色。
GlobalKey _key = GlobalKey(); _Container(_key), OutlineButton( child: Text('global key 刷新'), onPressed: () { _key.currentState.setState(() {}); },
点击globalKey
刷新局部小部件,点击右下角刷新整个页面。可以看到局部刷新时,只有下边的小部件改变颜色,整个页面刷新时。
效果:
注意