Flutter 布局真经,小白看完都会了
“OK,那我想要。
First child: “OK,那我想要
290像素的宽度,20个像素的长度。”
Widget: “嗯…由于我想要将我的第二个子级放在第一个子级下面,所以我们仅剩
55个像素的高度给第二个子级了。”
Widget: “嘿,我的第二个子级,你的宽度必须要在
0到290,长度在0到55之间。”
Second child: “OK,那我想要
140像素的宽度,30个像素的长度。”
Widget: “很好。我的第一个子级将被放在
x: 5&y: 5的位置,而我的第二个子级将在x: 80&y: 25的位置。”
Widget: “嘿,我的父级,我决定我的大小为
300像素宽度,60像素高度。”
====================================================================
约束Constraints 在Flutter中是一种_布局协议_,Flutter中有两大布局协议BoxConstraints和SliverConstraints。对于非滑动的控件例如Padding,Flex等一般都使用_BoxConstraints盒约束_。
约束可以分为:宽松约束(loose)和 严格约束(tight) 就widget布局树而言,约束默认向下传递,可有些布局类复写了performLayout改变了约束行为,将向下传递的约束信息改变甚至重建,从而导致有些布局行为变得不可预测,因此就需要掌握一些常用布局的布局原理,才能对整体的布局行为加以分析。
案例一:Container的约束失效
ConstrainedBox(
constraints: BoxConstraints.tightFor(
width: double.infinity,
height: double.infinity),
child: Container(width: 100, height: 100, color: red)
)
上边的案例,展示了一个预期宽100,高100的红色方块,可实际上只会得到一个满屏幕的红色。 虽然Container内部有宽高的约束,但是在这里是不起作用的,究其原因,是因为Container内部的布局特性引起的,父部件传递一个tight紧布局,而到了Container由于内部使用的ConstrainedBox,其布局行为会做如下改变:
@override
// this.constraints 为父部件传递的约束
void performLayout() {
final BoxConstraints constraints = this.constraints; // this.constraints为父部件传递过来的约束
if (child != null) {
// 在这里改变了约束,可能会导致自身设置的约束失效
child!.layout(_additionalConstraints.enforce(constraints),
parentUsesSize: true);
size = child!.size;
} else {
size = _additionalConstraints.enforce(constraints).constrain(Size.zero);
}
}
// clamp方法会自行在约束范围境内选择
BoxConstraints enforce(BoxConstraints constraints) {
return BoxConstraints(
minWidth: minWidth.clamp(constraints.minWidth, constraints.maxWidth),
maxWidth: maxWidth.clamp(constraints.minWidth, constraints.maxWidth),
minHeight: minHeight.clamp(constraints.minHeight, constraints.maxHeight),
maxHeight: maxHeight.clamp(constraints.minHeight, constraints.maxHeight),
);
}
按照先前的布局原理来说,Container告诉父布局自己需要一个100x100的空间,而父布局也有充分的空间提供,那预期的效果应该会很好的呈现,可在这里由于ConstrainedBox内部改变了布局行为,导致预期结果不生效,ConstrainedBox会通过enforce函数衡量自身的约束属性即 _additionalConstraints,和父布局传递的约束,在其中取临近值,在这里由于父部件约束为:
BoxConstraints(
minWidth: double.infinity,
maxWidth: double.infinity,
minHeight: double.infinity,
maxHeight: double.infinity,
);
故所以_additionalConstraints的约束行为会被改成double.infinity~double.infinity之间的值即double.infinity。
案例二:奇怪的LimitedBox
现有这样两个场景:
ConstrainedBox(
constraints: BoxConstraints.tightFor(
width: double.infinity,
height: double.infinity),
child: UnconstrainedBox(
child: LimitedBox(
maxWidth: 100,
child:
Container(color: Colors.red, width: double.infinity, height: 100),
),
)
)
ConstrainedBox(
constraints: BoxConstraints.tightFor(
width: double.infinity,
height: double.infinity),
child: Center(
child: LimitedBox(
maxWidth: 100,
child:
Container(color: Colors.red, width: double.infinity, height: 100),
),
)
)
两者的区别不是很明显,只是前者的LimitedBox由UnconstrainedBox包裹,而后由Center包裹,但两个例子所展示的UI却大相径庭: 

这样看来是Center致使LimitedBox的maxWidth约束失效了,为什么会这样呢?
// LimitedBox的布局过程
BoxConstraints _limitConstraints(BoxConstraints constraints) {
return BoxConstraints(
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。



由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
总结
可以看出,笔者的工作学习模式便是由以下 「六个要点」 组成:
❝ 多层次的工作/学习计划 + 番茄工作法 + 定额工作法 + 批处理 + 多任务并行 + 图层工作法❞
希望大家能将这些要点融入自己的工作学习当中,我相信一定会工作与学习地更富有成效。
下面是我学习用到的一些书籍学习导图,以及系统的学习资料。每一个知识点,都有对应的导图,学习的资料,视频,面试题目。
**如:我需要学习 **Flutter的知识。(大家可以参考我的学习方法)
点击这里了解更多即可领取!
- Flutter 的思维导图(无论学习什么,有学习路线都会事半功倍)

- Flutter进阶学习全套手册

- Flutter进阶学习全套视频

点击这里了解更多即可领取!
- Flutter 的思维导图(无论学习什么,有学习路线都会事半功倍)
[外链图片转存中…(img-pzsyrVAo-1710658875770)]
- Flutter进阶学习全套手册
[外链图片转存中…(img-Rw658YcJ-1710658875771)]
- Flutter进阶学习全套视频
[外链图片转存中…(img-s27KQVMA-1710658875771)]
大概就上面这几个步骤,这样学习不仅高效,而且能系统的学习新的知识。
更多推荐



所有评论(0)