Widget构建
我的评价是不要想太多, 知道即可, 这张笔记有点杂乱
Flutter 架构图
Widget在Flutter中的作用
在Flutter中,所有的元素都是Widget,Widget是Flutter世界里对视图的一种结构化描述,是控件实现的基本逻辑单位。我们可以将Widget理解为前端中的“组件”。Widget存储的是视图渲染的配置信息,包括布局、渲染属性、事件响应等。
Widget的基本类型
Flutter中有两种基本类型的Widget:
StatelessWidget
:这是一个静态的Widget
,它的状态在其生命周期内是不可变的。StatefulWidget
:这是一个动态的Widget
,它的状态在其生命周期内是可变的。
Widget的渲染过程
在Flutter中,视图的渲染过程主要分为三个部分:Widget
、Element
和 RenderObject
。
1. Widget
Widget是Flutter中的基本构建单元。它是一种视图描述,包含视图的配置信息,如布局、样式、事件处理等。在Flutter中,几乎所有的UI组件都是Widget,包括按钮、 文本、布局容器等。Widget本身是不可变的,每次状态改变时,Flutter会创建新的Widget实例。
2. Element
Element是Widget的实例化对象,承载了视图构建的上下文数据。它是连接结构化的配置信息到最终渲染的桥梁。Element树是对Widget树的一种具体实现,Element树中的节点对应于Widget树中的节点,但Element树是可变的。
Element的主要作用:
- 持有Widget的配置信息。
- 创建和管理RenderObject。
- 处理Widget树的变化,将变化反映到RenderObject树中。
3. RenderObject
RenderObject负责具体的布局和绘制工作。它接收来自Element的配置信息,进行视图的布局计算和绘制操作。RenderObject树是最终用于渲染的树结构,包含了所有需要渲染的对象。
RenderObjectWidget
前面我们介绍到StatelessWidget
和 StatefulWidget
只是用来组装控件的容器,并不负责组件最后的布局和绘制。
RenderObjectWidget
定义了一些方法来间接地管理 RenderObject
和 Element
,但具体的创 建与更新操作是在 RenderObjectElement
中进行的。下面我们详细解析这些方法。
abstract class RenderObjectWidget extends Widget {
@override
RenderObjectElement createElement();
@protected
RenderObject createRenderObject(BuildContext context);
@protected
void updateRenderObject(BuildContext context, covariant RenderObject renderObject);
@protected
void didUnmountRenderObject(covariant RenderObject renderObject) {}
}
createElement
: 返回一个RenderObjectElement
,这个方法由子类实现,用于创建Element
。createRenderObject
: 返回一个RenderObject
,这个方法由子类实现,用于创建RenderObject
。updateRenderObject
: 更新RenderObject
的属性,这个方法由子类实现,用于更新RenderObject
的属性。didUnmountRenderObject
: 当RenderObject
从树中移除时调用,可以在子类中重写这个方法以执行必要的清理工作。
RenderObjectElement
RenderObjectElement
继承自 Element
,它负责 RenderObject
的具体创建和管理操作。
// RenderObjectElement 继承自 Element,是一种特殊类型的 Element,
// 它与 RenderObjectWidget 一起工作以管理 RenderObject。
abstract class RenderObjectElement extends Element {
// 构造函数,接受一个 RenderObjectWidget 实例作为参数。
RenderObjectElement(RenderObjectWidget widget) : super(widget);
// 重写 widget getter 方法,将其强制转换为 RenderObjectWidget 类型。
@override
RenderObjectWidget get widget => super.widget as RenderObjectWidget;
// 持有的 RenderObject 实例。
RenderObject _renderObject;
// mount 方法在元素首次插入到树中时调用。
@override
void mount(Element parent, dynamic newSlot) {
super.mount(parent, newSlot);
// 创建 RenderObject,并将其附加到渲染树上。
_renderObject = widget.createRenderObject(this);
attachRenderObject(newSlot);
_dirty = false;
}
// update 方法在元素需要更新时调用。
@override
void update(RenderObjectWidget newWidget) {
super.update(newWidget);
// 更新 RenderObject 的属性。
widget.updateRenderObject(this, _renderObject);
_dirty = false;
}
// unmount 方法在元素从树中移除时调用。
@override
void unmount() {
super.unmount();
// 执行 RenderObject 的清理工作。
widget.didUnmountRenderObject(_renderObject);
}
// performRebuild 方法在需要重建元素时调用。
@override
void performRebuild() {
super.performRebuild();
// 更新 RenderObject 的属性。
widget.updateRenderObject(this, _renderObject);
}
// attachRenderObject 方法将 RenderObject 附加到渲染树上。
void attachRenderObject(dynamic newSlot) {
// 实现将 RenderObject 附加到渲染树的代码
}
// detachRenderObject 方法将 RenderObject 从渲染树上分离。
void detachRenderObject() {
// 实现将 RenderObject 从渲染树分离的代码
}
}