精彩评论
- al2359(2年前 (2023-02-06))
求科学离线插件,谢谢!34401355@qq.com
评:改版梅林固件安装SS【shadowsocks】科学上网插件教程 - al2359(2年前 (2023-02-06))
求科学离线插件,谢谢!!!
评:改版梅林固件安装SS【shadowsocks】科学上网插件教程
我们知道,flutter有三颗树,widget树在每次setState的时候都会重建,而element树不会,而是会通过diff算法,计算出哪些element需要重建,哪些element可以重用,我们通过一个例子来开始,例如
import 'dart:math';
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
final _random = Random();
class _HomePageState extends State<HomePage> {
var _items = [
ListItem(title: "aaa"),
ListItem(title: "bbb"),
ListItem(title: "ccc"),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("key demo"),
),
body: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: _items,
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
// 删除第一个元素
_items.removeAt(0);
setState(() {});
},
),
);
}
}
/// 定义一个item
class ListItem extends StatelessWidget {
final String title;
// color放在widget
final Color color = Color.fromARGB(
255, _random.nextInt(256), _random.nextInt(256), _random.nextInt(256));
ListItem({this.title});
@override
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
child: Text(
this.title,
style: TextStyle(color: Colors.white, fontSize: 20),
),
color: this.color,
width: 100,
height: 100,
);
}
}
运行正常,接下来我们把ListItem换成stateful
class ListItem extends StatefulWidget {
final String title;
ListItem({this.title});
@override
_ListItemState createState() => _ListItemState();
}
class _ListItemState extends State<ListItem> {
// color放在state
final Color color = Color.fromARGB(
255, _random.nextInt(256), _random.nextInt(256), _random.nextInt(256));
@override
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
child: Text(
widget.title,
style: TextStyle(color: Colors.white, fontSize: 20),
),
color: this.color,
width: 100,
height: 100,
);
}
}
从上图可以看出,颜色和文字混了,这是由于element树判断增量更新重用element导致的
当widget重建的时候,element通过对比新旧两个widget是否需要更新,从而判断是否重用,默认的逻辑是对比runtimeType
和key
,我们上面的例子中显然会返回true(我们没有定义key),则表示可以element可以直接使用新的widget
static bool canUpdate(Widget oldWidget, Widget newWidget) {
return oldWidget.runtimeType == newWidget.runtimeType
&& oldWidget.key == newWidget.key;
}
由于颜色是state持有的,没有变化,所以蓝色的element,直接使用了灰色的widget,而最后一个绿色的element,没有用到,会被释放
通过canUpdate方法可以看到,我们可以设置key来标识element是否可以直接更新widget,flutter中的key有两种
LocalKey
GlobalKey
LocalKey
LocalKey有下面三种,其成员key用于比较,使用起来类似
ValueKey: 使用一个泛型数据作为key
ObjectKey: 使用一个对象作为key
UniqueKey: 自动生成key,并且保证唯一,比较少用
// 在StatefulWidget构造方法添加参数key,并传给super
class ListItem extends StatefulWidget {
final String title;
ListItem({this.title, Key key}) : super(key: key);
@override
_ListItemState createState() => _ListItemState();
}
// 使用ListItem的时候,传入key
var _items = [
ListItem(title: "aaa", key: ValueKey<String>("aaa")),
ListItem(title: "bbb", key: ValueKey<String>("bbb")),
ListItem(title: "ccc", key: ValueKey<String>("ccc")),
];
这样在判断的时候不同的ListItem会在canUpdate方法就会返回false,就不会重用了
通常我们在自定义StatefulWidget的时候,需要在构造函数添加可选参数key
GlobalKey
GlobalKey可以获取到context(element),widget,和state,通常用于在父widget操作子widget
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
final GlobalKey<_TestWidgetState> _globalKey = GlobalKey();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("global key"),
),
body: Center(
child: TestWidget(
key: _globalKey,
)),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
// 直接操作子widget的state
_globalKey.currentState.increseCount();
},
),
);
}
}
class TestWidget extends StatefulWidget {
TestWidget({Key key}) : super(key: key);
@override
_TestWidgetState createState() => _TestWidgetState();
}
class _TestWidgetState extends State<TestWidget> {
int _count = 0;
increseCount() {
setState(() {
_count = _count + 1;
});
}
@override
Widget build(BuildContext context) {
return Text("$_count");
}
}
「梦想一旦被付诸行动,就会变得神圣,如果觉得我的文章对您有用,请帮助本站成长」
下一篇:Flutter组件集录,桌面导航,NavigationRail
求科学离线插件,谢谢!34401355@qq.com
评:改版梅林固件安装SS【shadowsocks】科学上网插件教程求科学离线插件,谢谢!!!
评:改版梅林固件安装SS【shadowsocks】科学上网插件教程