在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 ( Column
, Row
,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);
}
}