无状态小部件类中的钥匙是什么



在flutter文档中,有无状态小部件子类的示例代码,如下所示:

class GreenFrog extends StatelessWidget {
  const GreenFrog({ Key key }) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return new Container(color: const Color(0xFF2DBD3A));
  }
}

和这个

class Frog extends StatelessWidget {
  const Frog({
    Key key,
    this.color: const Color(0xFF2DBD3A),
    this.child,
  }) : super(key: key);
  final Color color;
  final Widget child;
  @override
  Widget build(BuildContext context) {
    return new Container(color: color, child: child);
  }
}

什么是钥匙,什么时候应该使用此超级构造函数?似乎如果您有自己的构造函数,则必须有{键键}为什么?我已经看到了其他示例,其中超级关键字是未使用的,所以这就是我的困惑。

tldr:所有小部件都应将Key key作为可选参数或其构造函数。 Key是Flutter Engine在识别列表中哪个小部件的步骤中使用的。


当您拥有 list ( ColumnRow,erthing(时,这很有用。

假设您有这个(代码不起作用,但您明白了(:

AnimatedList(
  children: [
    Card(child: Text("foo")),
    Card(child: Text("bar")),
    Card(child: Text("42")),
  ]
)

可能,您可以用滑动单独删除这些小部件中的任何一个。

事实是,当孩子被删除时,我们的列表有一个动画。因此,让我们删除" bar"。

AnimatedList(
  children: [
    Card(child: Text("foo")),
    Card(child: Text("42")),
  ]
)

问题:如果没有Key,Flutter将无法知道Row的第二个元素是否消失。或者,如果这是最后一个消失,而第二个则改变了孩子。

因此,如果没有Key,您可能会有一个错误,而您的 well 动画将在最后一个元素上播放!


这是Key发生的地方。

如果我们再次启动示例,使用键,我们将拥有以下内容:

AnimatedList(
  children: [
    Card(key: ObjectKey("foo"), child: Text("foo")),
    Card(key: ObjectKey("bar"), child: Text("bar")),
    Card(key: ObjectKey("42"), child: Text("42")),
  ]
)

注意键是如何而不是 儿童索引,而是元素独有的东西。

从这一点开始,如果我们再次删除" bar",我们将拥有

AnimatedList(
  children: [
    Card(key: ObjectKey("foo"), child: Text("foo")),
    Card(key: ObjectKey("42"), child: Text("42")),
  ]
)

多亏了key的存在,Flutter Engine现在确定要删除哪个窗口小部件。现在,我们的 well 动画将在" bar"上正确播放,而不是" 42"。

什么是键?

密钥是小部件的ID。所有小部件都有它们,而不仅仅是无状态窗。元素树使用它们来确定小部件是否可以重复使用或是否需要重建。如果未指定键(通常情况(,则使用小部件类型来确定这一点。

为什么使用键?

密钥可用于保持状态时,当小部件的数量或位置更改时。如果没有钥匙,那么颤音框架可能会对哪个小部件更改感到困惑。

何时使用密钥?

仅在框架需要帮助才能知道要更新哪个小部件时使用它们。

大多数情况下,您不需要使用密钥。由于密钥主要仅对保持状态有用,因此,如果您有一个无状态的小部件,其孩子都是无家可归的,那么就无需在其上使用钥匙。在这种情况下,使用钥匙不会有任何伤害,但也不会有帮助。

您可以使用键进行一些微观耗尽。请参阅本文。

在哪里使用键?

将钥匙放在正在进行重新排序或添加/删除的小部件树的一部分。例如,如果您要重新排序孩子是ListTile小部件的listView的项目,请在ListTile小部件中添加键。

使用什么样的密钥?

键只是一个ID,但是您使用的ID种类可能会有所不同。

valuekey

valuekey是一个本地密钥,它采用简单的值,例如字符串或整数。

objectKey

如果小部件显示的数据比单个值更复杂,则可以使用该小部件的对象键。

uniquekey

这种类型的键每次都能为您提供独特的ID。但是,如果使用它,请不要将其放入build方法中。否则您的小部件将永远不会具有相同的ID,因此元素树永远找不到重复使用的匹配。

GlobalKey

GlobalKeys可用于维护您在应用程序上的状态,但由于它们类似于全局变量,因此很少使用它们。通常最好使用状态管理解决方案。

使用密钥

的示例
  • AnimatedLists
  • 更改列/行中的位置
  • textformfield

参考

  • 钥匙!它们对什么有益?
  • 在flutter中使用键

键是用于识别窗口小部件的对象。

它们用于在StatefulWidget中访问或恢复状态(如果我们的小部件树都是无状态的小部件,则根本不需要它们(。我将尝试根据用法来解释各种类型的钥匙。

目的(key types(

1。在状态小部件(如可拖动待办事项列表(中突变集合 i.e. remove / add / reorder item to list 在其中删除了检查项目

➡️ObjectKey, ValueKey & UniqueKey

2。将小部件从一个父母移动到另一个保存状态的父母。

➡️GlobalKey

3。在多个屏幕中显示相同的小部件并保持其状态。

➡️GlobalKey

4。验证形式。

➡️GlobalKey

5。您想在不使用任何数据的情况下给密钥。

➡️UniqueKey

6。如果您可以将某些数据字段(例如用户的UUID(作为唯一键。

➡️ValueKey

7。如果您没有任何独特的字段用作密钥,但对象本身是唯一的。

➡️ObjectKey

8。如果您有多种形式或多个需要GlobalKey的类型的小部件。

➡️GlobalObjectKey, LabeledGlobalKey whichever is appropriate, similar logic to ValueKey and ObjectKey

❌请勿将随机string/number用作键,它会破坏键的目的❌

键是保存状态所需的可选参数小部件树,如果要移动树上的元素集合并保留它们的状态,则必须使用它们。

最好的解释可以在Google的视频中找到何时使用键 - flutter小部件101 EP。4

使用飞镖2.12或更高版本,在键之后添加 ?,以使其可选。

class Frog extends StatelessWidget {
  const Frog({
    Key? key,
    this.color: const Color(0xFF2DBD3A),
    this.child,
  }) : super(key: key);
  final Color color;
  final Widget child;
  @override
  Widget build(BuildContext context) {
    return new Container(color: color, child: child);
  }
}

最新更新