一切皆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. spring-boot-plus运维部署(八)

    spring-boot-plus运维部署 线上部署 打包环境为prod mvn clean package -Pprod 打包后的目录 cd target/spring-boot-plus-1.2.0 ...

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

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

  3. 基础部分之System、Object、Calendar、StringBuffer

    System.out.println(obj)和 System.out.println(obj.toString())区别 public static void main(String[] args) ...

  4. python实例:利用jieba库,分析统计金庸名著《倚天屠龙记》中人物名出现次数并排序

    本实例主要用到python的jieba库 首先当然是安装pip install jieba 这里比较关键的是如下几个步骤: 加载文本,分析文本 txt=open("C:\\Users\\Be ...

  5. 蓝桥杯单片机CT107D 01 底层驱动基础

    代码下载 https://share.weiyun.com/5NHvLxG 这两个代码文件是其他底层驱动代码的基础: 包含了控制138573(间接控制数码管led和蜂鸣器等).delay延时函数.CT ...

  6. HTML连载33-背景定位

    一.背景定位 同一个标签可以同时设置背景颜色和背景图片,如果颜色和图片同时存在,那么图片会覆盖颜色 1.在CSS中有一个叫做background-position:属性,就是专门用来控制背景图片的位置 ...

  7. 玩转 SpringBoot 2 快速整合 | 丝袜哥(Swagger)

    概述 首先让我引用 Swagger 官方的介绍: Design is the foundation of your API development. Swagger makes API design ...

  8. 7.解决在python中用selenium启动FireFox浏览器启动不了的方法

    首次在利用python中的selenium启动FireFox浏览器时可能碰到如下问题 当输入如下代码时: from selenium import webdriver brower=webdriver ...

  9. c# webapi结合swagger的使用

    一.使用nuget下载swagger包 Install-Package Swashbuckle 二.配置swagger 1. 安装完Swashbuckle后,nuget会将相关引用添加至WebApi项 ...

  10. 掀起你的盖头来:浅谈项目管理办公室(PMO)

    [提示]本文为“分享:<PMBOOK>读书笔记系列”由傻瓜(来自人人都是产品经理6群)编写. 之前与大家一定对项目.项目管理.项目集.项目组合等知识进行了简单的学习,如果有不太清楚和不太明 ...