一切皆Widget

Widget 渲染过程

Flutter把视图数据的组织和渲染抽象为三部分,即 Widget、Element 和 RenderObject。

Widget

Widget 是空间实现的基本逻辑单位,里面存储的是有关视图渲染的配置信息,包括布局、渲染属性、事件响应信息等。

页面渲染遵循“Simple is best”(简单是最好的)理念。Flutter 将 Widget 设计成不可变的,所以当视图渲染的配置信息发生变化时,Flutter 会选择重建 Widget 树的方式进行数据更新,以数据驱动 UI 构建的方式简单高效。

缺点是,因为涉及到大量对象的销毁和重建,所以会对垃圾回收造成压力。但是,Widget 本身并不涉及实际渲染位图,所以它只是一份轻量级的数据结构,重建成本很低。

另外,由于 Widget 的不可变行,可以以较低成本进行渲染节点复用,因此在一个真实的渲染树中可能存在不同的 Widget 对应同一个渲染节点的情况,这无疑又降低了重建 UI 的成本。

Element

Element 是 Widget 的一个实例化对象,它承载了视图构建的上下文数据,是连接结构化的配置信息到完成最终渲染的桥梁。

Flutter 渲染过程,可以分三步:

  • 首先,通过 Widget 树生成对应的 Element树;
  • 然后,创建相应的 RenderObject 并关联到 Element.renderObject 属性上;
  • 最后,构建成 RenderObject 树,以完成最终的渲染。

Element 同时持有 Widget 和 RenderObject,无论是 Widget 还是 Element,其实都不负责最后的渲染,只负责发号施令,真正干活儿的只有 RenderObject。

为什么不直由 Widget 命令 RenderObject 去干活儿,而是增加 Element 树?

Widget 直接命令,会极大地增加渲染带来的性能损耗。

因为 Widget 具有不可变性,但 Element 却是不可变的。实际上,Element 树这一层将 Widget 树的变化(类似 React 虚拟 DOM diff)做了抽象,可以只将真正需要修改的部分同步到真实的 RenderObject 树中,最大程度降低对真实渲染视图的修改,提高渲染效率,而不是销毁整个渲染视图树重建。

RenderObject

RenderObject 是主要负责实现视图渲染的对象。

渲染对象树在 Flutter 的展示过程分为四个阶段,即布局、绘制、合成和渲染。其中,布局和绘制在 RenderObject 中完成,Flutter 采用深度优先机制遍历渲染对象树,确定树中各个对象的位置和尺寸,并把它们绘制到不同的图层上。绘制完毕后,合成和渲染的工作则交给 Skia 搞定。

Flutter 通过引入 Widget、Element 与 RenderObject 这三个概念,把原本从视图数据到视图渲染的复杂构建过程拆分得更简单、直接,在易于集中治理的同时,保证了较高的渲染效率。

RenderObjectWidget 介绍

在 Flutter 中,布局和绘制工作实际上是在 Widget 的另一个子类 RenderObjectWidget 内完成的。RenderObjectWidget 源码如下:

RenderObjectWidget 是一个抽象类。这个类中同时拥有创建 Element、RenderObject,以及更新 RenderObject 的方法。但实际上,RenderObjectWidget 本身并不负责这些对象的创建与更新。

对于 Element 的创建,Flutter 会在遍历 Widget 树时,调用 createElement 去同步 Widget 自身配置,从而生成对应节点的 Element 对象。而对于 RenderObject 的创建与更新,其实是在 RenderObjectElement 类中完成。

在 Element 创建完毕后,Flutter 会调用 Element 的 Mount 方法。在这个方法里,会完成与之关联的 RenderObject 对象的创建,以及与渲染树的插入工作,插入到渲染树后的 Element 就可以显示到屏幕中了。

如果 Widget 的配置数据发生了改变,那么持有该 Widget 的 Element 节点会被标记为 dirty。在下一个周期的绘制时,Flutter 就会触发 Element 树的更新,并使用最新的 Widget 数据更新自身以及关联的 RenderObject 对象,接下来便会进入 Layout 和 Paint 的流程。而真正的绘制和布局过程,则完全交由 RenderObject 完成:

布局和绘制完成后,接下来的事情就交给 Skia 了。在 VSync 信号同步时直接从渲染树合成 Bitmap,然后提交给 GPU。

Widget 基础的更多相关文章

  1. iOS widget开发

    链接: iOS Widget开发 iOS开发之构建Widget iOS开发Widget iOS开发-widget基础 ios8新特性widget开发 ios 10 开发-widget实现 Widget ...

  2. 【转】谈谈Google Polymer以及Web UI框架的未来

    原文转自:http://www.csdn.net/article/2013-05-27/2815450-google-polymer 摘要:开发者Axel Rauschmayer在自己的博客上详解了G ...

  3. (24)odoo中模型标识汇总

    * 设置->技术->数据结构->模型                模型    模型描述    类型    瞬态模型account.account    科目    基础对象    ...

  4. Google Polymer以及Web UI框架

    时代在进步,原本前端只是用来简单的数据显示以及提交数据到后端处理逻辑的地方,而随着SPA的发展,前端的逻辑也越来越是庞大,恰巧,今天看微博的时候,发现一个概念讨论的比较多,就是 Web Compone ...

  5. 【JavaScript】谈谈Google Polymer以及Web UI框架的未来

    摘要:开发者Axel Rauschmayer在自己的博客上详解了Google Polymer的设计理念与组成架构,深得Polymer开发者的认同.他认为Polymer这样高互操作性的设计才应该是Web ...

  6. 十二、Android UI开发专题(转)

    http://dev.10086.cn/cmdn/bbs/viewthread.php?tid=18736&page=1#pid89255Android UI开发专题(一) 之界面设计 近期很 ...

  7. 【COCOS2DX-对28游戏开发】 Cocos2d-x-3c 道路设计 CocosBase CocosNet CocosWidget

    原文链接:http://blog.csdn.net/cocosviva/article/details/18970717 另一个比較不错的cocos2dx扩展库:https://github.com/ ...

  8. Android UI开发专题(转)

    http://dev.10086.cn/cmdn/bbs/viewthread.php?tid=18736&page=1#pid89255 Android UI开发专题(一) 之界面设计 近期 ...

  9. odoo 开发基础 -- 视图之widget

    Odoo 中的widget many2many_tags one2many_list selection progressbar selection statusbar handle monetary ...

随机推荐

  1. [SCOI2007]压缩(动态规划,区间dp,字符串哈希)

    [SCOI2007]压缩 状态:设\(dp[i][j]\)表示前i个字符,最后一个\(M\)放置在\(j\)位置之后的最短字串长度. 转移有三类,用刷表法来实现. 第一种是直接往压缩串后面填字符,这样 ...

  2. 浏览器DOM渲染及阻塞问题

    在准备面试,然后复习到了计网的知识点,紧接着又扯到了url从输入到浏览器渲染的那个问题,这里来顺便完善补充一下,本文的重点在渲染 上面的图就是浏览器从服务器请求来页面后渲染的全过程 这里我们分开来看: ...

  3. java IO流 之 FIle类基础

    package IO; import java.io.File;import java.io.IOException; public class FileIO { /** * 构建及获取文件名信息 * ...

  4. odoo t标签用法

    在odoo中,通过QWeb来对模板进行渲染后加载到浏览器中,而模板中有许多的标签来定制各种需求变化,在这里记录学习过程中碰到的标签定义,以方便查询. 模板中的标签统一都是以"t-" ...

  5. HDU 1517

    题意略. 思路: 我们分别来考虑n取到的各个区间,从而发现其中的规律: [2,9] 明显 Stan 必胜. 但是当n = 9 + 1时,Stan无论如何也不能取胜,并且此时,假设 Stan 取值 x ...

  6. 安装hadoop集群--hdfs

    安装hadoop集群--hdfs 大数据软件 链接:https://pan.baidu.com/s/1-3PYLHMgvvONawJq55hstQ 提取码:izqf 准备一台干净的虚拟机-centos ...

  7. Leetcode之深度优先搜索(DFS)专题-129. 求根到叶子节点数字之和(Sum Root to Leaf Numbers)

    Leetcode之深度优先搜索(DFS)专题-129. 求根到叶子节点数字之和(Sum Root to Leaf Numbers) 深度优先搜索的解题详细介绍,点击 给定一个二叉树,它的每个结点都存放 ...

  8. iOS仿写下厨房

    把之前简书的博客搬到博客园了,还是放在一个地方看着舒服. 先看一下做的效果,是不是还不错?(可以看一下早餐那块的轮播,上面盖着一个都是点点的图片,但是它不是和轮播一起滚动的,是盖在轮播上面的,需要在那 ...

  9. matplotlib 库的使用

    1.问题描述: 在学习kaggle经典学习项目Titanic,进行数据可视化处理时,对于每个特征进行相关性分析(也就是绘制pearson correlation heatmap )热力相关性矩阵时, ...

  10. SDU暑期集训排位(9)

    SDU暑期集训排位(9) G. Just Some Permutations 基础 DP 练习部分 定义 \(f(S)\),表示让 S 中的人全 happy 的方案数. \(dp[i][j]\) 表示 ...