为什么说Flutter万物皆Widget?首先你要知道,Flutter是什么,它是一个现代的响应式框架、一个2D渲染引擎、现成的widget和开发工具,基于Skia,一个性能彪悍的2D图像绘制引擎,2005年被Google收购,被广泛应用于Chrome和Android之上,等等吧,说白一点,Flutter就是一个UI框架,所以说,万物皆Widget,而Widget的中文意思是小部件,它为什么不能像Android或者Ios一样叫做View呢?因为widget既可以是一个结构元素(如按钮或菜单)、也可以是一个文本样式元素(如字体或颜色方案)、布局的一个方面(如填充)等等,我们可以统筹它们为wiget,而不是view,根据基本的命名规范,这就是一种合理的命名抽象。那么接下来我们学什么?
- Widget是什么
- Widget类结构
- 跟着我实现一个widget(直接继承widget抽象类)
- Element类结构
- 深入理解Element
其实上面说了,一切皆Widget,那我们可不可以认为,在flutter的框架中,用到的东西都是Widget呢,当然不是哈,由于它是基于Dart,所以有很多Dart的库,还是可以使用的,比如AES,RSA加密解密,Json序列化等等,但你可以这么说,一切构建图形相关的东西都是Widget,这就是Widget
为什么说下类结构呢?类结构可以很清晰帮助我们梳理逻辑,从全局的角度看待整个结构
![image](/assets/images/01-316c5793a0711ff91a2227134339d79c.webp)
- RenderObjectWidget 看名字我们判断,它是持有RenderObject对象的Widget,而通过其他通道了解到,RenderObject实际上是完成界面的布局、测量与绘制,像Padding,Table,Align都是它的子类
- StatefulWidget 多了一个State状态的Widget,子类都是可以动态改变的如CheckBox,Switch
- StatelessWidget 就是一个普通的Widget,不可变如Icon,Text。
- ProxyWidget InheritedWidget就是它的子类,我们暂且认为它是子类能从父类拿数据的关键,以后再研究,大多数的主题都是继承自ProxyWidget
我不想和别人的教程思路一样,既然万物皆Widget,那我们就从实现一个Widget开始,然后一步步深入,看到什么就去了解什么?来上代码
class TestWidget extends Widget{
@override
Element createElement() {
// TODO: implement createElement
throw UnimplementedError();
}
}
创建一个TestWidget然后继承Widget,然后会让你重写函数createElement,返回一个Element,通过这个我们看的出,其实我们创建的Widget,最终肯定是创建了一个Element,那Element到底是什么呢?同样的思路,我们继承Element看一下
class TestElement extends Element{
TestElement(Widget widget) : super(widget);
@override
bool get debugDoingBuild => throw UnimplementedError();
@override
void performRebuild() {
}
}
多了一个构造函数,传递Widget对象,get函数debugDoingBuild,还有performRebuild函数,都是干嘛的呢?
abstract class Element extends DiagnosticableTree implements BuildContext
abstract class BuildContext {
/// Whether the [widget] is currently updating the widget or render tree.
///
/// For [StatefulWidget]s and [StatelessWidget]s this flag is true while
/// their respective build methods are executing.
/// [RenderObjectWidget]s set this to true while creating or configuring their
/// associated [RenderObject]s.
/// Other [Widget] types may set this to true for conceptually similar phases
/// of their lifecycle.
///
/// When this is true, it is safe for [widget] to establish a dependency to an
/// [InheritedWidget] by calling [dependOnInheritedElement] or
/// [dependOnInheritedWidgetOfExactType].
///
/// Accessing this flag in release mode is not valid.
bool get debugDoingBuild;
经过代码的跟踪我们发现一些注解:
- Element继承自DiagnosticableTree,并实现BuildContext
- DiagnosticableTree是个“诊断树”,主要作用是提供调试信息。
- BuildContext类似原生系统的上下文,它定义了debugDoingBuild,通过注解我们知道,它应该就是一个debug用的一个标志位。
- performRebuild 经过源码查看后发现,由rebuild()调用如下
void rebuild() {
if (!_active || !_dirty)
return;
performRebuild();
}
@override
void update(ProxyWidget newWidget) {
rebuild();
}
首先说明下,这个并不是Element的源码,我摘自StatelessElement,是Element的子类,这说明在update函数后,Element就会直接执行performRebuild函数,那我们完善下自定义的Element逻辑
class TestElement extends Element {
TestElement(Widget widget) : super(widget);
@override
bool get debugDoingBuild => throw UnimplementedError();
@override
void performRebuild() {
}
@override
void update(Widget newWidget) {
super.update(newWidget);
print("TestWidget update");
performRebuild();
}
@override
TestWidget get widget => super.widget as TestWidget;
Widget build() => widget.build(this);
}
在update的时候执行performRebuild(),但是performRebuild执行什么呢?我们结合一下StatelessElement的实现,发现,它调用了传递进来的Widget参数build函数,那么我们就在TestWidget中添加函数,并完善下逻辑后是这样的
class TestWidget extends Widget {
@override
Element createElement() {
/// 将自己传递进去,让Element调用下面的build函数
return TestElement(this);
}
/// 这个context其实就是Element
Widget build(BuildContext context) {
print("TestWidget build");
return Text("TestWidget");
}
}
class TestElement extends Element {
Element _child;
TestElement(Widget widget) : super(widget);
@override
bool get debugDoingBuild => throw UnimplementedError();
@override
void performRebuild() {
///调用build函数
var _build = build();
///更新子视图
_child = updateChild(_child, _build, slot);
}
@override
void update(Widget newWidget) {
super.update(newWidget);
print("TestWidget update");
///更新
performRebuild();
}
///将widget强转成TestWidget
@override
TestWidget get widget => super.widget as TestWidget;
/// 调用TestWidget的build函数
Widget build() => widget.build(this);
}
然后将其放入main.dart中如图
![image](/assets/images/02-8ca8daa6956f9c6c4457c9d845523528.webp)
最终效果展示,如图
[图片上传失败...(image-72eee6-1600853501724)]
展示出来了,我们简单总结一下,到目前你学到了什么?
- Widget会创建Element对象(调用createElement并不是Widget,而是Framework)
- Widget并没有实际的操控UI
- Element是在update的时候重新调用Widget的build函数来构建子Widget
- updateChild会根据传入的Widget生成新的Element
- Widget的函数build,传入的context其实就是它创建的Element对象,那么为什么这么设计呢?一方面它可以隔离掉一些Element的细节,避免Widget频繁调用或者误操作带来的不确定问题,一方面context上下文可以存储树的结构,来从树种查找元素。
其实可以很简单的理解为,Widget就是Element的配置信息,在Dart虚拟机中会频繁的创建和销毁,由于量比较大,所以抽象一层Element来读取配置信息,做一层过滤,最终再真实的绘制出来,这样做的好处就是避免不必要的刷新。接下来我们深入了解下Element
在深入了解Element之前我们也从全局看下它的结构
![image](/assets/images/03-39bb7755ad52b4974baab155bc80230e.webp)
可以看到,Element最主要的两个抽象:
- ComponentElement
- RenderObjectElement
都是干嘛的呢?经过看源码,发现ComponentElement,其实做了一件事情就是在mount函数中,判断Element是第一次创建,然后调用_firstBuild,最终通过rebuild调用performRebuild,通过上面我们也知道performRebuild最终调用updateChild来绘制UI
而RenderObjectElement就比较复杂一点,它创建了RenderObject,通过RenderObjectWidget的createRenderObject方法,通过以前的学习,我们也知道RenderObject其实是真正绘制UI的对象,所以我们暂且认为RenderObjectElement其实就是可以直接操控RenderObject,一种更直接的方式来控制UI。
为什么要深入理解Element呢,由于大多数情况下,我们开发者并不会直接操作Element,但对于想要全局了解FlutterUI框架至关重要,特别实在一些状态管理的框架中,如Provider,他们都定制了自己的Element实现,那么这么重要,我们需要从哪方面了解呢?一个很重要的知识点就是生命周期,只有了解了正确的生命周期,你才能在合适的时间做合适的操作
![image](/assets/images/04-b76d5dafcd139743147e78bf6fcf8b89.webp)
为了验证该图,我们加入日志打印下,代码如下:
/// 创建LifecycleElement 实现生命周期函数
class LifecycleElement extends TestElement{
LifecycleElement(Widget widget) : super(widget);
@override
void mount(Element parent, newSlot) {
print("LifecycleElement mount");
super.mount(parent, newSlot);
}
@override
void unmount() {
print("LifecycleElement unmount");
super.unmount();
}
@override
void activate() {
print("LifecycleElement activate");
super.activate();
}
@override
void rebuild() {
print("LifecycleElement rebuild");
super.rebuild();
}
@override
void deactivate() {
print("LifecycleElement deactivate");
super.deactivate();
}
@override
void didChangeDependencies() {
print("LifecycleElement didChangeDependencies");
super.didChangeDependencies();
}
@override
void update(Widget newWidget) {
print("LifecycleElement update");
super.update(newWidget);
}
@override
Element updateChild(Element child, Widget newWidget, newSlot) {
print("LifecycleElement updateChild");
return super.updateChild(child, newWidget, newSlot);
}
@override
void deactivateChild(Element child) {
print("LifecycleElement deactivateChild");
super.deactivateChild(child);
}
}
class TestWidget extends Widget {
@override
Element createElement() {
/// 将自己传递进去,让Element调用下面的build函数
/// 更新TestElement为LifecycleElement
return LifecycleElement(this);
}
/// 这个context其实就是Element
Widget build(BuildContext context) {
return Text("TestWidget");
}
}
然后改造下main.dart, 如下
///添加变量
bool isShow = true;
/// 加入变量控制
isShow ? TestWidget() : Container(),
/// 将floatingActionButton改为这样的实现
onPressed: () {
setState(() {
isShow = !isShow;
});
},
运行一下项目查看日志
![image](/assets/images/05-62634c879a1df706343c865b094d5a09.webp)
- 调用 element.mount(parentElement,newSlot)
- 调用 update(Widget newWidget)
- 调用 updateChild(Element child, Widget newWidget, newSlot)
然后我们点击下按钮
![image](data:image/webp;base64,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)
- 调用 deactivate()
- 调用 unmount()
我们再点击下按钮
![image](data:image/webp;base64,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)
这次只有mount,为什么?由于Widget本身不可变,我判断是因为这个导致的,那如何判断呢?下面介绍一个小技巧,其实flutter的framework层是可以加入调试代码的,我们加入日志看下,如下:
/// widget 基类其实有一个canUpdate函数,我们猜测肯定是这里导致的,加入日志如下
static bool canUpdate(Widget oldWidget, Widget newWidget) {
if(oldWidget.toString()=="TestWidget") {
print("canUpdate${oldWidget.runtimeType == newWidget.runtimeType
&& oldWidget.key == newWidget.key}");
}
return oldWidget.runtimeType == newWidget.runtimeType
&& oldWidget.key == newWidget.key;
}
是个静态函数,肯定是在Element中被调用的,我们找下
@mustCallSuper
void update(covariant Widget newWidget) {
if (newWidget.toString() == "TestWidget") {
print("TestWidget update start");
}
assert(_debugLifecycleState == _ElementLifecycle.active
&& widget != null
&& newWidget != null
&& newWidget != widget
&& depth != null
&& _active
&& Widget.canUpdate(widget, newWidget));
assert(() {
_debugForgottenChildrenWithGlobalKey.forEach(_debugRemoveGlobalKeyReservation);
_debugForgottenChildrenWithGlobalKey.clear();
return true;
}());
if (newWidget.toString() == "TestWidget") {
print("TestWidget:${newWidget.hashCode}");
}
_widget = newWidget;
}
如上代码是Element的源码,这里调用了canUpdate函数,如果不需要更新的话,就直接中断了执行,我们重新运行下demo,并在加一个print来验证一下newWidget是什么样子的,这里加入newWidget.toString() == "TestWidget",主要是为了过滤垃圾日志,重新运行项目。如图
![image](/assets/images/08-ad5ef5cb2fc3b15b36f827da5b9ac214.webp)
点击后按钮
![image](/assets/images/09-9eb5d5136a8913c0d993ba186b224235.webp)
再点击
![image](data:image/webp;base64,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)
发现并没有调用canUpdate,那我们如何让它重新加载回来呢?我们查查资料,改造下例子
@override
void mount(Element parent, newSlot) {
print("LifecycleElement mount");
super.mount(parent, newSlot);
assert(_child == null);
print("LifecycleElement firstBuild");
performRebuild();
}
mount函数加入performRebuild()函数,最终会触发updateChild,加assert断言是防止后面再加载进来的时候多次触发updateChild,然后改造下main.dart
@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: isShow ? TestWidget() : Container(),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
isShow = !isShow;
});
},
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
去掉Column,这里是由于我们没有处理widget的index逻辑,导致在Column里不正常,后续我们再研究为什么,先来看下生命周期的回调
第一次运行
[图片上传失败...(image-be90d-1600853501724)]
点击按钮
![image](/assets/images/11-5352e73bb7ea09b3fac5c7227c274c7c.webp)
又发现一个问题,为什么我们的断言没生效呢?怎么又出现了firstBuild?哈哈,这里不要纠结,由于TestWidget并非const,导致setState后,又重新被创建了,而对应的Element也同样是创建了新的值,最终导致被重新执行。其实这个TestWidget已经不是上一个了,那我们加入 const修饰再看看
/// 改成const
const TestWidget()
/// 加入当前widget hashcode输出,用来判断两次是否一致
@override
void mount(Element parent, newSlot) {
print("LifecycleElement widget hashcode${widget.hashCode}");
print("LifecycleElement hashcode${this.hashCode}");
print("LifecycleElement mount");
super.mount(parent, newSlot);
assert(_child == null);
print("LifecycleElement firstBuild");
performRebuild();
}
最终(启动,点击按钮两次的效果)运行效果如下:
![image](/assets/images/12-a7cffc222fe1e5a7d5dca13646fae17c.webp)
两次运行Widget保持一致,这就避免了Widget的重建
经过测试我们发现:
- Widget的创建可以做到复用,通过const修饰
- Element并没有复用,其实原因应该是在于isShow为false的时候导致其被deactivate 然后unmount,从Element树种被移除掉。
- 有的人肯定有些疑问,怎么全程没看到activate呢?它不应该属于生命周期的一部分吗?这个就需要用到Key了,在接下来的课程里,讲到Key的时候,我们再详细的学习。
本期我们对Widget,Element有了一个详细的认知,但其实它还有一个State类(StatefulWidget的核心实现)和RenderObject类,这两个下期我再分析。