21*:Flutter之Key:ValueKey、ObjectKey、UniqueKey、GlobalKey

问题

 

目录

 

预备

 

正文

1:Key 是什么?

用官方的说法就是:

key是用来作为WidgetElementSemanticsNode的标示,仅仅用来更新widget->key相同的小部件的状态。

Key子类包含LocalKeyGlobalKey

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来刷新其他小部件。

GlobalObjectKeyObjectKey是否相等的判定条件是一致的,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刷新局部小部件,点击右下角刷新整个页面。可以看到局部刷新时,只有下边的小部件改变颜色,整个页面刷新时。

效果:

 

注意

 

引用

1:Flutter 详解 (五、深入了解Key)

2:Flutter 详解 Key

posted on 2020-12-10 21:28  风zk  阅读(2449)  评论(0编辑  收藏  举报

导航