做为系列文章的第六篇,本篇主要在前文的探索下,针对描述一下 Widget 中的一些有意思的原理。git
前文:github
首先咱们须要明白,Widget 是什么?这里有一个 “总所周知” 的答就是:Widget并不真正的渲染对象 。是的,事实上在 Flutter 中渲染是经历了从 Widget
到 Element
再到 RenderObject
的过程。bash
咱们都知道 Widget 是不可变的,那么 Widget 是如何在不可变中去构建画面的?上面咱们知道,Widget
是须要转化为 Element
去渲染的,而从下图注释能够看到,事实上 Widget 只是 Element 的一个配置描述 ,告诉 Element 这个实例如何去渲染。布局
那么 Widget 和 Element 之间是怎样的对应关系呢?从上图注释也可知: Widget 和 Element 之间是一对多的关系 。实际上渲染树是由 Element 实例的节点构成的树,而做为配置文件的 Widget 可能被复用到树的多个部分,对应产生多个 Element 对象。post
那么RenderObject
又是什么?它和上述两个的关系是什么?从源码注释写着 An object in the render tree
能够看出到 RenderObject
才是实际的渲染对象,而经过 Element 源码咱们能够看出:Element 持有 RenderObject 和 Widget。优化
再结合下图,能够大体总结出三者的关系是:配置文件 Widget 生成了 Element,然后建立 RenderObject 关联到 Element 的内部 renderObject
对象上,最后Flutter 经过 RenderObject 数据来布局和绘制。 理论上你也能够认为 RenderObject 是最终给 Flutter 的渲染数据,它保存了大小和位置等信息,Flutter 经过它去绘制出画面。ui
说到 RenderObject
,就不得不说 RenderBox
:A render object in a 2D Cartesian coordinate system
,从源码注释能够看出,它是在继承 RenderObject
基础的布局和绘制功能上,实现了“笛卡尔坐标系”:以 Top、Left 为基点,经过宽高两个轴实现布局和嵌套的。spa
RenderBox 避免了直接使用 RenderObject
的麻烦场景,其中 RenderBox
的布局和计算大小是在 performLayout()
和 performResize()
这两个方法中去处理,不少时候咱们更多的是选择继承 RenderBox
去实现自定义。code
综合上述状况,咱们知道:orm
因此针对是否每次都须要建立出新的 Element 和 RenderObject 对象,Widget 都作了对应的判断以便于复用,好比:在 newWidget
与oldWidget
的 runtimeType 和 key 相等时会选择使用 newWidget
去更新已经存在的 Element 对象,否则就选择从新建立新的 Element。
由此可知:Widget 从新建立,Element 树和 RenderObject 树并不会彻底从新建立。
看到这,说个题外话:那通常咱们能够怎么获取布局的大小和位置呢?
首先这里须要用到咱们前文中提过的 GlobalKey
,经过 key 去获取到控件对象的 BuildContext
,而咱们也知道 BuildContext
的实现实际上是 Element
,而Element
持有 RenderObject
。So,咱们知道的 RenderObject
,实际上获取到的就是 RenderBox
,那么经过 RenderBox
咱们就只大小和位置了。
showSizes() {
RenderBox renderBoxRed = fileListKey.currentContext.findRenderObject();
print(renderBoxRed.size);
}
showPositions() {
RenderBox renderBoxRed = fileListKey.currentContext.findRenderObject();
print(renderBoxRed.localToGlobal(Offset.zero));
}
复制代码
--
自此,第六篇终于结束了!(///▽///)
《Flutter完整开发实战详解(1、Dart语言和Flutter基础)》
《Flutter完整开发实战详解(4、Redux、主题、国际化)》
《Flutter完整开发实战详解(6、 深刻Widget原理)》
《Flutter完整开发实战详解(10、 深刻图片加载流程)》
《Flutter完整开发实战详解(11、全面深刻理解Stream)》
《React Native 的将来与React Hooks》