无状态小部件类中的键是什么?

问题描述 投票:40回答:1

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

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);
  }
}

什么是关键,什么时候应该使用这个超级构造函数?好像你有自己的构造函数,你必须有{Key key}为什么?我已经看到了其他没有使用super关键字的例子,所以这就是我的困惑所在。

dart flutter
1个回答
74
投票

TLDR:所有小部件都应该有一个Key key作为可选参数或它们的构造函数。 Key是flutter引擎在识别列表中哪个窗口小部件已更改的步骤中使用的内容。


当你有一个可能被删除/插入的相同类型的小部件列表(ColumnRow,无论如何)时,它很有用。

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

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,颤动将无法知道你的Row的第二个元素是否消失了。或者,如果它是最后一个消失,第二个有它的孩子改变。

所以没有Key,你可能会有一个错误,你的离开动画将在最后一个元素上播放!


这是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的存在,颤振引擎现在知道哪个小部件被删除了。现在,我们的离开动画将正确播放“bar”而不是“42”。


3
投票

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

Google When to Use Keys - Flutter Widgets 101 Ep. 4在此视频中可以找到最佳解释

© www.soinside.com 2019 - 2024. All rights reserved.