Flutter 组件分析之LayoutBuilder
本系列教程基于Flutter widget, 意在为Flutter 入门提供基础建设. 重点在讲解widget 的 用法,参数以及扩展.
适宜人群: 入门
引语
LayoutBuilder 通常用于构建一个依赖于父 widget 大小的 widget 树. 换句话来说, 就是父对象约束子对象大小并且不依赖子对象的大小.
LayoutBuilder
本次, 我们从源码出发结合实例看一下 LayoutBuilder 的实现. LayoutBuilder 基于 ConstrainedLayoutBuilder 实现. ConstrainedLayoutBuilder 基于 RenderObjectWidget 实现. RenderObjectWidget 中提供了 RenderObjectElement 以及 RenderObject 的创建. 在 ConstrainedLayoutBuilder 中, 帮助我们创建了 RenderObjectElement . 所以在 LayoutBuilder 中, 我们仅负责 RenderObject 的创建. 可以看到最终 RenderObject 返回的是 _RenderLayoutBuilder 对象. 我们分析下关于 _RenderLayoutBuilder
_RenderLayoutBuilder
在 _RenderLayoutBuilder 中, 我们可以看到以下方法都返回了 0.0 . 也就是说此时, 我们已经申明了不再考虑子 widget 的尺寸大小. 因此最终我们布局时并不考虑子尺寸, 因为它是基于父 widget 尺寸提供的.
我们在绘制布局的时候 (这里仅说明一下有 child 的场景). 在 child 调用 layout 后. 通过自己的 constraints 去强迫 child 的size 改变.
这里的 child size 都通过了 constrainWidth\constrainHeight 的方法去做一个限制, 也就是基于 constraints 的范围内, 尽可能布局. 我们用两个示例来解释.
我们创建一个 200 * 200 的蓝色Container , 在它的内部分别放入 100 *100 和100 *500 的红色 Container . 分别看下两种情况下, 它们的表现:
示例1
100*100 时:
示例2
100*500 时:
通过示例我们可以看出, 实际上 child 的宽高并不会超出父 widget 允许的最大宽高, 所以超出部分实际上是被截断的; 而小于父 widget 时, 则会正常展示.
hitTestChildren
剩下比较重要的就是关于它点击事件了. LayoutBuilder 本身实际上是不处理的, 它会返回自身 child 的命中结果. 当然了, 如果没有 child , 它自身也会默认返回false, 不去消费点击事件. 其实这也能理解, LayoutBuilder 本身没有任何 ui 上的绘制. 用户没有视觉交互自然也不需要点击事件了.
思考
类似于 LayoutBuilder 的设计, 我们可以参考 CustomSingleChildLayout. 同样都是基于父 widget 的约束范围来做布局的 widget 组件. 学习了 LayoutBuilder 之后, 最大的感触还是 constraints 的灵活运用. 知己知彼方能百战不殆!
这里是WeninerIo😇
如果你对这次的技术分享感兴趣或者有什么疑惑🧐
不妨在评论区留言或私信🤪
或许这次的分享不是你所期待的😣
那就点个关注吧! 🙏
下次也许就是你中意的呢🫣?