介绍
作为该系列的第七篇文章,本文主要是在上一篇文章的基础上,进一步了解了Widget和布局中的一些常识性问题。
前言:
1.Dart语言和Flutter基础知识
2、实践中快速发展
3、包装及填坑
四、Redux、主题、国际化
5、深入探索
6. 深入Widget原理
第六篇文章我们知道了Widget、Element、RenderObject之间的关系。 其中,我们最熟悉的Widgetelementui布局写法,是以“配置文件”的形式存在的。 在Flutter中,其功能比较简单,属于“粒度比较细的颗粒存在”,编写代码就像拼乐高“积木”,那么这些“积木”到底是如何组装的呢? 让我们更深入地挖掘有趣的东西。 ( ̄▽ ̄)
1. 列表元素布局
Flutter中单个子元素的布局Widget中,Container无疑是应用最广泛的,因为从“功能”上来说,它并不像Padding等Widget那样功能单一。 为什么?
其原因,从右边的源码可以看出,Container实际上只是将其他“单一”的Widget重新封装,然后进行配置,从而达到“多功能疗效”。
那么我们先看一下ConstrainedBox的源码。 从右边的源码可以看出,它继承了SingleChildRenderObjectWidget。 关键是重写createRenderObject方法并返回RenderConstrainedBox。
这里重点介绍第六篇中的Widget和RenderObject的关系
是的,RenderConstrainedBox继承自RenderBox,实现RenderObject的布局。 在这里我们得到他们的关系如下:
然后我们继续观察其他各个Widget,可以看到它们都继承了SingleChildRenderObjectWidget,而“简单地说”它们之间的区别就是RenderObject的实现:
所以我们可以得出结论:真正的布局和尺寸估计都是在RenderBox上实现的。 不同的Widget通过各自的RenderBox实现“差异化”的布局效果。 所以找到每个Widget的实现,找到它的RenderBox实现。
这里我们用Offstage Widget来总结一下。 Offstage Widget通过offstage标志来控制child是否显示的效果。 同样,它也有一个RenderOffstage,如下图所示。 通过RenderOffstage的源码,我们可以“真正”看到offstage标志的作用:
那么很多时候我们的Widget都是通过实现RenderBox来实现布局的,那么我们是不是可以扔掉Widget,直接使用RenderBox呢? 答案显然是肯定的,如果你太忙的话!
为了治愈我们的“痛苦”,Flutter官方提供了一个名为CustomSingleChildLayout的类,它体现了一个名为SingleChildLayoutDelegate的对象,以便你可以更方便地操作RenderBox来实现自定义效果。
如下面的三个源代码所示,SingleChildLayoutDelegate对象提供了以下socket,并且按顺序调用前三个socket。 通过实现这个socket,你可以轻松控制RenderBox的布局位置和大小。
二、多子元素布局
其实“多子元素布局”和单子元素布局类似,我们可以通过“举一反三”来知道它们的关系,例如:
同样,“多子布局”也提供了CustomMultiChildLayout和MultiChildLayoutDelegate来满足你的“痛苦”需求。
3.多子元素滑动布局
滑动布局是“多子元素布局”的另一个分支,例如ListView、GridView、Pageview。 它们的实现要复杂得多。 从右边的一个过程我们可以大致知道他们的关系:
从上图我们可以知道,该过程最终会形成两个RenderObject:
并且从RenderViewport的描述中我们知道RenderBox不能直接放在RenderViewport内部,需要通过RenderSliver家族来完成布局。 从源码中我们可以看到RenderViewport对应的Widget Viewport是一个MultiChildRenderObjectWidget。 (看,再次回到 MultiChildRenderObjectWidget。)
我们稍微说一下上图的流程:
注意TabBarView里面是:NotificationListener + PageView
你觉得缺少什么吗? 哈哈哈elementui布局写法,有的,官方还提供了自定义滑动的CustomScrollView,解决了“痛点”。 它继承了ScrollView,可以通过slivers参数实现布局。 这些条子最终通过Scrollable buildViewport添加到ViewPort中,如下面的代码所示:
不知道大家看完这篇文章后,是否对Flutter的布局有了更深入的了解呢? 让我们一起享受堆砌积木的乐趣吧!
结语
自此,第七章就结束了! 想解读Flutter完整开发的教程和资料,想一起交流学习的同事可以私信我!
发表评论