Flutter Key作用是什么?



文章目录

  • Flutter Key作用是什么?
  • 前言
  • 一、Key是什么?Key的作用?
  • 需要用Key的时候没有用key的例子
  • 需要用Key的时候没有用key的例子(有key)
  • Key是什么
  • 二、Flutter里Widget和Element的对应关系
  • 一、Widget和Element在没有key的状态下是如何匹配的
  • WidgetTree和ElementTree是什么

  • 二、Widget和Element在有key的状态下是如何匹配的
  • 总结



前言

可能当你学习Flutter的路上没有人会告诉你key是什么,但是在这里我会给你key。


一、Key是什么?Key的作用?

在Flutter中每个Widget的构造方法都提供了一个可选参数Key(可以打开源码看看),那我们什么时候才会用到key呢?或者在需要用Key的时候我们没有用Key会发生什么事呢,下面我们来看一看当需要用到Key的时候没有用Key会产生什么样的反应把。

需要用Key的时候没有用key的例子

代码如下(示例):一个简单的程序当点击按钮时+1,

@override
  Widget build(BuildContext context) {
   
    return Scaffold(
      appBar: AppBar(
        
        title: Text(widget.title),
      ),
      body: Center(
        
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Box(Colors.blue),
            Box(Colors.orange),

          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

class Box extends StatefulWidget{
  final Color color;

  const Box(this.color); //const Box(this.color , Key key) : super(key: key); (使用key)

  @override
  _BoxState createState() => _BoxState();
}

class _BoxState extends State<Box> {
  int _count = 0;

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Container(
        width: 100,
        height: 100,
        color: widget.color,
        child: Center(
          child: RaisedButton(
            onPressed: ()=> setState(() => _count++),
            child: Text("$_count",style:TextStyle(fontSize: 24),
            ),
          ),
        ),
    );
  }
}

flutter hive可以存储多大的数据 flutter key的用处_sed


那么当两个Box互换位置,答案会是什么呢?

body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Box(Colors.orange),
            Box(Colors.blue),
          ],
        ),
      ),

flutter hive可以存储多大的数据 flutter key的用处_flutter_02


我们可以发现只是颜色发生了变化,但是数字却没有随着改变,大家也可以再添加一个BOX玩耍,出来的结果是比较有趣的(可以试试三个同样演示的BOX),因为文章太长不适于阅读这里就不再多做演示

我们可以看到Flutter已经分不清楚你到底要怎么修改组件布局了,那么Colors不可以充当Widget的唯一标识,需要一个类似ID的属性,那么我们Key的作用就来了 。

需要用Key的时候没有用key的例子(有key)

稍作修改

body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Box(Colors.orange,ValueKey(123)),
            Box(Colors.blue,ValueKey(234)),
          ],
        ),
      ),


const Box(this.color , Key key) : super(key: key);

无论我们怎么样玩弄这个Box,Flutter 也会认识这个Widget

Key是什么

keys 可以保留 widget 的状态。在实际使用中,keys 对于保留用户的滚动状态或在需要修改集合 (collection) 时保持状态。

二、Flutter里Widget和Element的对应关系

一、Widget和Element在没有key的状态下是如何匹配的

WidgetTree和ElementTree是什么

注:不涉及源码解释,作者能力有限

flutter hive可以存储多大的数据 flutter key的用处_ios_03


WidgetTree:是组件树,WidgetTree有很多个级别的组件,只有同一级别的组件才会在一个同一个Column(所以在这个我们要观察的同一级别的组件是Box)

ElementTree:是组件对应的实例集合,这里我们就可以理解为什么State要分为(less 和 ful)因为如果是ful的话 BoxElement里面都需要有一个State状态去控制实例,这也是为什么改变需要重新SetState因为WidgetTree里面的组件只是一个蓝图,而控制和属性在ColumnElement上

当我们去改变蓝图时(WidgetTree),Flutter会重绘对应的Widget ,那么当我们去改变WidgetTree里面的控件顺序的时候,ColumnElement并不会发生任何改变那么,原本一一对应的关系就是杂乱不堪,这个时候就需要我们的key出场了。

二、Widget和Element在有key的状态下是如何匹配的

flutter hive可以存储多大的数据 flutter key的用处_android_04


举例:

  • 当我们删掉Box(key:1)时,Flutter进行热重载后,BoxElement因找不到Box(key:1)对象而自杀了。是Element从Column队列中寻找,可以理解为Element主动找Box(key:1)对象 最后找遍邻居家也找不到然后自杀了(●’◡’●)。
  • 那么解释到这里key的作用也显而易见了,就是让每一个BoxElement都找到自己的对象,找不到就自杀。
  • 那么如果没有key的话,最先去找Box的Element就会把Box搬回家,后面再去找的要么不合意要么找不到对象自杀了
  • 因为我们能运用的key的场景也不多,因为很少存在这种多种同一widget在同一个阶级里(WidgetTree的阶级)即使我们平时很少用到key但是key的工作原理及作用我们也非常有必要知道

总结

文章没有过多的代码和图片详解,因为大量的代码和图片会影响同学的阅读兴趣,所以我再这里让大家容易的理解key是怎么一回事,具体的代码不难实现自己也可以去多试试看我这个结论是否正确。本人学过很多东西,但是学起来都提不起兴趣,直到遇到了Flutter,Flutter的设计非常有意思,简约而不简单。祝大家乘风破浪