当前位置: 首页 > news >正文

搭建个人视频网站简述商务网站建设步骤

搭建个人视频网站,简述商务网站建设步骤,顺企网企业名录电话,更新wordpress图片地址【Flutter从入门到入坑】Flutter 知识体系 【Flutter从入门到入坑之一】Flutter 介绍及安装使用 【Flutter从入门到入坑之二】Dart语言基础概述 【Flutter从入门到入坑之三】Flutter 是如何工作的 WidgetWidget 是什么呢?Widget 渲染过程WidgetElementRenderObjectR…

【Flutter从入门到入坑】Flutter 知识体系
【Flutter从入门到入坑之一】Flutter 介绍及安装使用
【Flutter从入门到入坑之二】Dart语言基础概述
【Flutter从入门到入坑之三】Flutter 是如何工作的


Widget

    • Widget 是什么呢?
    • Widget 渲染过程
      • Widget
      • Element
      • RenderObject
      • RenderObjectWidget
    • 示例图解
    • 小结


今天我们一起学习 Widget 在 Flutter 中的设计思路和基本原理,以帮助我们更加深入理解 Flutter 的视图构建过程。

这张架构图很重要,我们再来看一下:

Flutter 架构图
不难看出: Widget 是整个视图描述的基础。


Widget 是什么呢?

Widget 是 Flutter 功能的抽象描述,是视图的配置信息,同样也是数据的映射,是 Flutter 开发框架中最基本的概念。前端框架中常见的名词,比如视图(View)、视图控制器(View Controller)、活动(Activity)、应用(Application)、布局(Layout)等,在 Flutter 中都是 Widget。

事实上,Flutter 的核心设计思想便是“一切皆 Widget”。所以,我们学习 Flutter,首先得从学会使用 Widget 开始。

下面,我们一起学习 Widget 在 Flutter 中的设计思路和基本原理,以帮助我们可以更加深入理解 Flutter 的视图构建过程。


Widget 渲染过程

我们在进行软件开发时,总会关注这样一个问题:如何结构化地组织视图数据,提供给渲染引擎,最终完成界面显示。

通常情况下,不同的 UI 框架中会以不同的方式去处理这一问题,但无一例外地都会用到视图树(View Tree)的概念。而 Flutter 将视图树的概念进行了扩展,把视图数据的组织和渲染抽象为三部分,即 Widget,Element 和 RenderObject。

这三部分之间的关系如下:
Widget,Element 与 RenderObject

Widget

Widget 是 Flutter 世界里对视图的一种结构化描述,你可以把它看作是前端中的“控件”或“组件”。Widget 是控件实现的基本逻辑单位,里面存储的是有关视图渲染的配置信息,包括布局、渲染属性、事件响应信息等。

Flutter 将 Widget 设计成不可变的,所以当视图渲染的配置信息发生变化时,Flutter 会选择重建 Widget 树的方式进行数据更新,以数据驱动 UI 构建的方式简单高效。所以,在页面渲染上,Flutter 将“Simple is best”这一理念做到了极致。

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

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

Element

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

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

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

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

那为什么需要增加中间的这层 Element 树呢?直接由 Widget 命令 RenderObject 去干活儿不好吗?

答案是:可以,但这样做会极大地增加渲染带来的性能损耗。
因为 Widget 具有不可变性,但 Element 却是可变的。实际上,Element 树这一层将 Widget 树的变化(类似 React 虚拟 DOM diff)做了抽象,可以只将真正需要修改的部分同步到真实的 RenderObject 树中,最大程度降低对真实渲染视图的修改,提高渲染效率,而不是销毁整个渲染视图树重建。
这,就是 Element 树存在的意义。

RenderObject

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

Flutter 通过控件树(Widget 树)中的每个控件(Widget)创建不同类型的渲染对象,组成渲染对象树。

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

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

RenderObjectWidget

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

所以,我们再来看一下 RenderObjectWidget 的源码,来看看如何使用 Element 和 RenderObject 完成图形渲染工作。

// RenderObjectWidget 源码
abstract class RenderObjectWidget extends Widget {RenderObjectElement createElement();RenderObject createRenderObject(BuildContext context);void updateRenderObject(BuildContext context, covariant RenderObject renderObject) { }...
}

RenderObjectWidget 是一个抽象类。我们通过源码可以看到,这个类中同时拥有创建 Element、RenderObject,以及更新 RenderObject 的方法。

但实际上,RenderObjectWidget 本身并不负责这些对象的创建与更新

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

// RenderObjectElement 源码
abstract class RenderObjectElement extends Element {RenderObject _renderObject;void mount(Element parent, dynamic newSlot) {super.mount(parent, newSlot);_renderObject = widget.createRenderObject(this);attachRenderObject(newSlot);_dirty = false;}void update(covariant RenderObjectWidget newWidget) {super.update(newWidget);widget.updateRenderObject(this, renderObject);_dirty = false;}...
}

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

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

// RenderObject 源码
abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin implements HitTestTarget {...void layout(Constraints constraints, { bool parentUsesSize = false }) {...}void paint(PaintingContext context, Offset offset) { }
}

布局和绘制完成后,接下来的事情就交给 Skia 了。在 VSync 信号同步时直接从渲染树合成 Bitmap,然后提交给 GPU。【在第三章「Flutter 是如何工作的」中有详细介绍,此处不在赘述】


示例图解

我们以下面的界面示例为例,说明 Widget、Element 与 RenderObject 在渲染过程中的关系。

在下面的例子中,一个 Row 容器放置了 4 个子 Widget,左边是 Image,而右边则是一个 Column 容器下排布的两个 Text。

界面示例

在 Flutter 遍历完 Widget 树,创建了各个子 Widget 对应的 Element 的同时,也创建了与之关联的、负责实际布局和绘制的 RenderObject。

下面是生成的“三棵树”:

示例界面生成的“三棵树”


小结

本文章介绍了 Widget 渲染过程,学习了在 Flutter 中视图数据的组织和渲染抽象的三个核心概念,即 Widget、 Element 和 RenderObject。

Widget 是 Flutter 世界里对视图的一种结构化描述,里面存储的是有关视图渲染的配置信息;Element 则是 Widget 的一个实例化对象,将 Widget 树的变化做了抽象,能够做到只将真正需要修改的部分同步到真实的 Render Object 树中,最大程度地优化了从结构化的配置信息到完成最终渲染的过程;而 RenderObject,则负责实现视图的最终呈现,通过布局、绘制完成界面的展示。

我们在日常开发学习中,绝大多数情况下,我们只需要了解各种 Widget 特性及使用方法,而无需关心 Element 及 RenderObject。因为 Flutter 已经帮我们做了大量优化工作,因此我们只需要在上层代码完成各类 Widget 的组装配置,其他的事情完全交给 Flutter 就可以了。


本章节内容主要是学习 陈航 老师的《Flutter 核心技术与实战》课程总结而来。

http://www.yayakq.cn/news/572003/

相关文章:

  • logo免费网站红河企业网络推广外包
  • 保定市网站制作公司wordpress搜索引擎优化
  • 餐饮手机网站建设超变攻速传奇一秒20刀
  • seo查询 站长工具公益基金会网站开发的背景
  • 北京网站推广公司排名网站建设去哪里找客户
  • 徐州网站建设推广wordpress大气
  • 店铺推广软文案例seo网站建设步骤
  • 博客网站代码响应式网页设计与制作
  • 做网站 做手机app要学什么软件沈阳网站建设制作公司
  • 提供网站建设课程代码wordpress论坛插件
  • 学做网站应该看那些书网站的备案在哪备案吗
  • 自己公司产品网站的好处花都区建设工程造价管理网站
  • 网站建设网站建设的网络公司纹理网站推荐
  • 自己做网站服务器多少钱网站建设叁金手指花总1
  • 万网官方网站南昌专门做网站的人
  • 山东省建筑施工企业安全生产管理网站关键词seo怎么做
  • 网站建设排序题石家庄网站定制开发
  • 平面设计做画册用网站1688官网登录入口
  • 网站建设维护合同范本联盟平台
  • 展览会建设网站平台的作用房产公司网站建设
  • 企业平台网站建设有人做网站吗
  • 网站建设app开发公司网站被iframe
  • php网站忘记后台密码wordpress归档页面模板
  • 整容医院网站建设目的做网站切图尺寸
  • 如何申请免费的网站空间国家军事网
  • 有哪些网站建设工作求职网站开发多少钱
  • 网站 优化 分析江苏新站优化
  • 电子商务基础平台有哪些seo短视频发布页
  • 电商网站建设比较好的苏中建设是哪里的
  • 无投入网站推广包头网站建设易通