什么是key

我们通过源码可以看到Key的定义:

  1. @immutable
  2. abstract class Key {
  3. const factory Key(String value) = ValueKey<String>;
  4. @protected
  5. const Key.empty();
  6. }
  • Key本身是一个抽象类;
  • 通过工厂构造方法可以创建一个ValueKey

image.png
通过ValueKey的定义可以发现,value可以使任意类型;

Key有两个直接子类:LocalKeyGlobalKey

  • LocalKey:是Flutter增量渲染算法的核心,通过LocalKey来决定Element是否需要保留或者删除;它有几个子类:
    • ValueKey:以值作为参数(数字、字符串);
    • ObjectKey:以对象作为参数;
    • UniqueKey:创建唯一标识;
  • GlobalKey:用来帮助我们确定某一个WidgetElement或者State,来访问其信息;它在整个程序中是唯一的

    GlobalKey的使用

    我们先来看一段代码:
    image.png
    我们想要通过点击按钮来改变Text中的数字,目前按照这个代码的逻辑是无法实现的,因为按钮在StatelessWidget中,如果想要改变某一个Widget的值,我们需要在按钮的点击方法中调用setState方法,而StatelessWidget是没有setState方法的;

按照我们之前的思路是无法实现的,但是通过GlobalKey可以达到同样的目的;

我们将GlobalKeyDemo的代码修改如下:
image.png

  • 我们在GlobalKeyDemo中创建一个GlobalKey用来获取_ChildPageState(想要通过GlobalKey获取什么,就在泛型中传什么。比如传ChildPage来直接获取ChildPage);
  • ChildPage构造函数中传key属性传值_globalKey
  • 因为在ChildPage的构造函数中调用了super,所以_globalKey将会和ChildPage绑定;

我们可以通过_globalKey获取相关信息:
image.png
我们将代码修改如下:
iShot2021-12-10 11.00.12.gif
按钮的点击方法实现如下:

  1. FloatingActionButton(
  2. child: const Icon(Icons.add),
  3. onPressed: () {
  4. _globalKey.currentState?.setState(() {
  5. _globalKey.currentState?.data = '谢谢' + _globalKey.currentState!.count.toString();
  6. _globalKey.currentState?.count ++;
  7. });
  8. },
  9. ),

通过_globalKey.currentState可以直接获取datacount等属性进行操作;

我们也可以创建多个GlobalKey来获取不同的组件;

我们一般通过GlobalKey来操作子部件,虽然也可以通过属性传值的方式将GlobalKey保存传递给其他非子部件使用,但是一般不推荐;