flutter key

随意点开一个Widget,就会发现,可以传递一个参数Key.那这个Key到底是干啥子,有什么用呢?

Flutter是受React启发的,所以Virtual Dom的diff算法也参考过来了(应该是略有修改),在diff的过程中如果节点有Key来比较的话,能够最大程度重用已有的节点(特别在列表的场景),除了这一点这个Key也用在很多其他的地方这个以后会总结一下。总之,这里我们可以知道key能够提高性能,所以每个Widget都会构建方法都会有一个key的参数可选,贯穿着整个框架。

通常情况下,我们不需要去传递这个Key。因为framework会在内部自处理它,来区分不同的widgets
下面有几种情况,我们可以使用它

- 使用ObjectKeyValueKey来对组件进行区分。

可以看PageStorageKey, 和另外一个例子,这个例子是deletion: https://flutter.io/cookbook/gestures/dismissible/.

简单的来说,当我们使用Row或者Column时,想要执行一个remove的动画

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

  

当我们移除"bar"后

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

  

因为我们没有定义Key,所以可能flutter并不知道,我们那个item发生了改变,所以可能发生在位置1上的动画,可能发生在其他位置。
正确的修改如下:

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

  

这样当我们移除"bar"的时候,flutter就能准确的区别到正确的位置上。
Key虽然不是Index,但是对于每一个元素来说,是独一无二的。

- 使用GlobalKey
  1. 使用GlobalKey的场景是,从父控件和跨子Widget来传递状态时。
    需要注意的是:不要滥用GlobalKey,如果有更好的方式的,请使用其他方式来传递状态。

这里有一个例子是 通过给Scaffold添加GolbalKey。然后通widget.GolbalKey.state来调用showSnackBar

class _MyHomePageState extends State<MyHomePage> {
  final globalKey =
      new GlobalKey<ScaffoldState>();

  void _incrementCounter() {
    globalKey.currentState
        .showSnackBar(SnackBar(content: Text('I am context from Scaffold')));
  }

 @override
  Widget build(BuildContext context) {
    return new Scaffold(
        key: globalKey,
      //...
      )
}
}

  

这样就可以直接从父控件调用子Widget的状态。

推荐视频 When to Use Keys - Flutter Widgets 101 Ep. 4

  1. 还有一个场景是,过渡动画,当两个页面都是相同的Widget时,也可以使用GlobalKey。

总之框架要求同一个父节点下子节点的Key都是唯一的就可以了,GlobalKey可以保证全局是唯一的,所以GlobalKey的组件能够依附在不同的节点上。

https://www.jianshu.com/p/e9f48141218d?tdsourcetag=s_pctim_aiomsg

猜你喜欢

转载自www.cnblogs.com/pythonClub/p/10590028.html
key