Flutter Key作用和原理

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

在这里插入图片描述
那么当两个Box互换位置,答案会是什么呢?

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

在这里插入图片描述
我们可以发现只是颜色发生了变化,但是数字却没有随着改变,大家也可以再添加一个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是什么

注:不涉及源码解释,作者能力有限
在这里插入图片描述
WidgetTree:是组件树,WidgetTree有很多个级别的组件,只有同一级别的组件才会在一个同一个Column(所以在这个我们要观察的同一级别的组件是Box)
ElementTree:是组件对应的实例集合,这里我们就可以理解为什么State要分为(less 和 ful)因为如果是ful的话 BoxElement里面都需要有一个State状态去控制实例,这也是为什么改变需要重新SetState因为WidgetTree里面的组件只是一个蓝图,而控制和属性在ColumnElement上

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

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

在这里插入图片描述
举例:

  • 当我们删掉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的设计非常有意思,简约而不简单。祝大家乘风破浪

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值