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),
),
),
),
);
}
}
那么当两个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的设计非常有意思,简约而不简单。祝大家乘风破浪