博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Flutter 视图体系概述
阅读量:5818 次
发布时间:2019-06-18

本文共 3392 字,大约阅读时间需要 11 分钟。

之前几篇文章都提过 Flutter 的思想十分类似 React,通过 Widget Tree 来表示整个 app 的视图。一般来讲,常规 app 的开发中我们只需要与 和它的子类打交道,然而 Widget 并不是我们真实看到的视图,本文就来简单介绍一下 Flutter 视图系统背后的细节。

首先先摆 3 个关键的概念:WidgetElementRenderObject

Widget

为了解释 Widget,我们先看看官方是如何定义它的:

Describes the configuration for an Element.

Widgets are the central class hierarchy in the Flutter framework. A widget is an immutable description of part of a user interface. Widgets can be inflated into elements, which manage the underlying render tree.

可以看到,Widget 的实际工作也就是描述如何创建 ElementWidget 是一个不可变对象,它可以被复用,请注意,这里的复用不是指在两次渲染的时候将对象从旧树中拿过来放到新树,而是在同一个 Widget Tree 中,某个子 Widget 可以出现多次,因为它只是一个 description。

在一次渲染中,Flutter Framework 会调用 Widget 的 方法,这个方法会创建一个新的对应的 对象并返回。所以即使 Widget 被重复使用,框架还是会创建多个不同的 Element 对象。 到这里,Widget 的工作就暂告一段落了。

Element

ElementWidget 的实例体现,上面说过 Widget 可以重复使用,但是 Flutter Framework 仍然会对这几个相同的 Widget 依次创建几个全新的 Element。 一次渲染会生成一个 Element Tree 并放在内存中,在下次渲染时 Flutter Framework 会用尝试用新的 Widget 去更新旧的 Element,此时 Element 被复用,这里的复用是指不再创建新的 Element 的对象了,但每个相同的 Widget 还是各自对应了一个不同的 Element(好像有点绕,不知道大家能不能理解 -。-)。

那么 Element 到底是做什么的呢,概括地说就是保存了一个树形结构以便更新时做 diff、patch 和管理组件生命周期用的,由于 Widget 都是没有状态的,如果你想修改 Widget 的某一属性就必须要重新创建一遍 Widget,而 StatefulWidget 内部包含 State,如果重新创建了状态就会丢失,所以必须有一个地方来存储这些暂时的状态。

StatefulWidget 来举例说明吧。 第一次渲染时,StatefulWidget 通过 createElement 创建出一个 StatefulElement,然后我们来看 StatefulElement 的构造方法:

StatefulElement(StatefulWidget widget)    : _state = widget.createState(), super(widget) {    assert(() {      if (!_state._debugTypesAreRight(widget)) {        throw new FlutterError(          'StatefulWidget.createState must return a subtype of State<${widget.runtimeType}>\n'          'The createState function for ${widget.runtimeType} returned a state '          'of type ${_state.runtimeType}, which is not a subtype of '          'State<${widget.runtimeType}>, violating the contract for createState.'        );      }      return true;    }());    assert(_state._element == null);    _state._element = this;    assert(_state._widget == null);    _state._widget = widget;    assert(_state._debugLifecycleState == _StateLifecycle.created);}复制代码

可以看到,StatefulElement 内部会负责创建和保存 State,这样就是为什么 StatefulWidget 被重新创建了而内部的状态不会丢失的原因。

然后在 Widget Tree 发生变化的时候,Flutter Framework 通过 Elementupdate 来根据新 Widget 更新旧 Element

@overridevoid update(StatefulWidget newWidget) {    super.update(newWidget);    assert(widget == newWidget);    final StatefulWidget oldWidget = _state._widget;    // Notice that we mark ourselves as dirty before calling didUpdateWidget to    // let authors call setState from within didUpdateWidget without triggering    // asserts.    _dirty = true;    _state._widget = widget;    try {      _debugSetAllowIgnoredCallsToMarkNeedsBuild(true);      _state.didUpdateWidget(oldWidget);    } finally {      _debugSetAllowIgnoredCallsToMarkNeedsBuild(false);    }    rebuild();}复制代码

所以如果你去看官方文档对 Element 的介绍,就会发现它就是负责状态和生命周期管理的对象,实际上很少需要去自己实现 Element

RenderObject

这个东西通过名字就能知道,它就是负责视图渲染的。实际上,所有的布局、绘制和事件响应全都由它负责,开发复杂视图时我们可能经常需要与之打交道。

而它又是由 Element 的子类 RenderObjectElement 创建出来的,RenderObject 也会构成一个 Render Tree,并且每个 RenderObject 也都会被保存下来以便在更新时复用。

通常我们也不直接 subclass RenderObject 本身,而是它的子类 RenderBoxRenderBox 帮我们实现了很多基础设施,然而它并不能容纳子 RenderObject,想要实现一个容器,我们需要使用 RenderObjectWithChildMixin<ChildType>mixin,它们提供了对 children 的支持。

由于 RenderObject 本身又涉及很多细节,所以本文不再深入探讨。


以上就是 Flutter 视图系统对外大致的结构,希望对大家学习 Flutter 开发有所帮助~

References

转载地址:http://czzdx.baihongyu.com/

你可能感兴趣的文章
C++_了解虚函数的概念
查看>>
全新jmeter视频已经上架
查看>>
Windows 8下如何删除无线配置文件
查看>>
解决Windows 7中文件关联和打开方式
查看>>
oracle系列(五)高级DBA必知的Oracle的备份与恢复(全录收集)
查看>>
hp 服务器通过串口重定向功能的使用
查看>>
国外10大IT网站和博客网站
查看>>
对java语言学习的个人看法
查看>>
android第十一期 - SmoothSwitchLibrary仿IOS切换Activity动画效果
查看>>
zabbix 批量web url监控
查看>>
大容量导入和导出数据 -- 格式化文件生成
查看>>
MongoDB CookBook读书笔记之导入导出
查看>>
shell如何快速锁定所有账号
查看>>
HTML 5实现的手机摇一摇
查看>>
Linux 文件IO理解
查看>>
Ninject 2.x细说---2.绑定和作用域
查看>>
30个非常时尚的网页联系表单设计优秀示例
查看>>
使用membership(System.Web.Security)来进行角色与权限管理
查看>>
opticom 语音质量验证白皮书
查看>>
3D实时渲染中的BSP树和多边形剔除
查看>>