likes
comments
collection
share

36、Flutter之布局类组件-布局类组件简介

作者站长头像
站长
· 阅读数 6

简介

布局类组件都会包含一个或多个子组件,不同的布局类组件对子组件排列(layout)方式不同。

Widget说明用途
LeafRenderObjectWidget非容器类组件基类Widget树的叶子节点,用于没有子节点的widget,通常基础组件都属于这一类,如Image。
SingleChildRenderObjectWidget单子组件基类包含一个子Widget,如:ConstrainedBox、DecoratedBox等
MultiChildRenderObjectWidget多子组件基类包含多个子Widget,一般都有一个childrens参数,接受一个Widget数组。如Row、Column、Stack等

布局类组件就是指直接或间接继承(包含)SingleChildRenderObjectWidgetMultiChildRenderObjectWidget的Widget,它们一般都会有一个child或children属性用于接收子 Widget。我们看一下继承关系 Widget > RenderObjectWidget > (Leaf/SingleChild/MultiChild)RenderObjectWidget 。

RenderObjectWidget类中定义了创建、更新RenderObject的方法,子类必须实现他们,关于RenderObject我们现在只需要知道它是最终布局、渲染UI界面的对象即可,也就是说,对于布局类组件来说,其布局算法都是通过对应的RenderObject对象来实现的,所以读者如果对接下来介绍的某个布局类组件的原理感兴趣,可以查看其对应的RenderObject的实现,比如Stack(层叠布局)对应的RenderObject对象就是RenderStack,而层叠布局的实现就在RenderStack中。

36、Flutter之布局类组件-布局类组件简介

Widget,Element 与 RenderObject

RenderObject属于底层渲染,一般项目开发很难接触到,实际项目中用的更多的是## Widget,Element,当然也要了解## Widget,Element 与 RenderObject的关系。 Element 是联系 Widget 和 RenderObject 的纽带。

  • Widget - 存放渲染内容、视图布局信息
  • Element - 存放上下文信息,通过 Element 遍历视图树,Element 同时持有Widget和RenderObject
  • RenderObject - 根据 Widget 的布局属性进行 layout,对 widget 传入的内容进行渲染绘制

首先通过一张图来看 Element 是如何发挥其纽带作用的:

36、Flutter之布局类组件-布局类组件简介

  • 每个 Widget 会创建一个对应的 Element 对象 (通过 Widget.createElement())
  • 每个 Element 会持有对应 Widget 对象的引用 (注意 createElement() 方法第一个参数)
  • RenderObjectElement 是 Element 的子类,这种 Element 持有一个 RenderObject 对象的引用

RenderObject

RenderObject是渲染树中的对象。

RenderObject类层次结构是渲染库存在的核心原因。

RenderObject有一个父对象,并且有一个名为parentData的插槽,父对象RenderObject可以在其中存储特定于子对象的数据,例如,子对象的位置。RenderObject类还实现了基本的布局和绘制协议。

然而,RenderObject类没有定义子模型(例如,一个节点是否有0个、1个或多个子模型)。它也没有定义一个坐标系统(例如,子节点是在笛卡尔坐标中定位还是在极坐标中定位等)或一个特定的布局协议(例如,布局是宽高向外,还是大小向外限制,或者父节点是在子节点布局之前还是之后设置子节点的大小和位置等);或者是否允许子节点读取父节点的parentData插槽)。

RenderBox子类引入了布局系统使用笛卡尔坐标的观点。 更多底层参考:api.flutter.dev/flutter/ren…