Flutter Layout 约束

由于最近赶项目比较忙没有更新,今天准备回顾下之前项目中遇到的一个小问题,研究了一下,还是比较有意思的。

事情是这样的,公司心来的实习生,写了一段代码,在设置大小的时候,总是不生效,于是我们研究了一下这个问题,分享给大家。

以下是简化后的代码和效果。


请仔细看,在第二层的子container中设置了大小就是不生效,我们稍加修改以下代码,看看效果。

我们在子container上加了一个center,子container设置的100,生效了,我们看到显示正常了。那么是什么原因导致了子container设置的大小不生效呢?

我们在现实生活中有在装箱打包,如果要装的内容太大,我们是装不进去的,这时我们就会选用更大的箱子来包装,也就是说最终,最外部的箱子多大是根据内容来的。

而在Flutter方面,手机屏幕的大小是固定的,也就是说我们最外部的箱子的大小已经是固定的了。当我们试图放一个较大的物品的时候,由于超过了固有尺寸,所以会被修改为最大尺寸。而上面的例子中,子内容的大小是100,父节点的大小是400,没有超过父节点的大小,为什么子节点还是显示了400呢?这里提到的就是Constraints。

Constraints 约束

Flutter中Constraints是一个抽象类,具体的布局模型需要实现这个抽象类,在父节点和子节点之间传达布局约束。Constraints有两个实现分别是BoxConstraints和SliverConstraints。找到Container的源码,我们看到使用的是BoxConstraints。

可以看到上面的注释,构造函数width和height参数与constraints参数结合使用以设置此属性。

扫描二维码关注公众号,回复: 15209648 查看本文章

BoxConstraints

Flutter框架中的渲染对象由一遍布局模型(one-pass layout model)进行布局,该模型沿渲染树传递约束向下走,然后沿渲染树返回具体几何形状。

每个RenderBox,从其父级接收BoxConstraints,然后对其每个子级进行布局,然后选择一个满足BoxConstraints的Size。

约束本身必须满足以下关系:

0.0 <= minWidth <= maxWidth <= double.infinity
0.0 <= minHeight <= maxHeight <= double.infinity

术语:

当最小约束和最大约束相同时,我们称之为(tight)严格约束;

当最小约束为0.0的时候,此时我们称之为(loose)松约束;

那么,最大约束和最小约束都是0的时候,就是即紧又松动的。

说了这么多,可能小伙伴还是有点懵,我们用代码来演示以下。对我们的代码稍加改动。

我们看到layoutbuilder中传递进来的BoxConstraints为严格约束,大小为400。此时无论子节点如何设置大小,都不会生效,因为布局的约束已经指定了只能是400。

我们在来修改以下代码,看看效果。

我们在外面加了一层center,我们设置的100大小就生效了,log中显示,center传递给子节点的约束属于宽松约束,允许子节点的大小在0-400之间。

以下是Flutter约束传递的简单理解,我这里假设了手机的root尺寸是400,实际上在上面的例子里,我们container之上还有Scaffold等widget,这些也是有约束限制的,所以这里省略简化了,感兴趣的可以继续研究以下。

向下传递约束,向上传递尺寸,最后父节点得到每个child信息之后在觉得把每个child放在哪里。

上面我们通过一个小例子,揭示了Flutter中一部分约束布局的相关内容。其他的widget比如padding、align等等都要受到约束的限制,可以去多多了解这个问题。

感谢大家的阅读,后面还会持续更新,开发过程中遇到的问题,也欢迎大家批评指正。

猜你喜欢

转载自blog.csdn.net/z2008q/article/details/113543584
今日推荐