当学习Flutter的人问你为什么width:100
的widget不是100像素宽时,默认的答案是告诉他widget放在Center里面,对吧?(不知原理,答非所问)
千万不要那样做
如果你这样做,他们会一次又一次地回来,问为什么有些FittedBox
不工作,为什么Column
溢出,或者IntrinsicWidth
应该做什么?
相反,首先告诉他们Flutter布局和HTML布局有很大的不同(这可能是他们的来源),然后让他们记住以下规则:
Constraints go down. Sizes go up. Parent sets position
不了解这个规则就无法真正理解Flutter布局,所以Flutter开发放着要早点学习:
更详细的:
- 小部件从其父级获得自己的Constraints。约束只是一组4个:最小和最大宽度,以及最小和最大高度。
- 然后小部件遍历它自己的子列表。小部件一个接一个地告诉它的孩子他们的约束是什么(每个孩子可能不同),然后询问每个孩子它想要的大小。
- 然后,小部件一个接一个地定位其子项(水平方向在x轴上,垂直方向在y轴行)。
- 最后,小部件将自己的大小告知其父级(当然在原始限制范围内)。
例如,如果一个组合小部件爱你包含一个带有一些填充的列,并且想要按如下方式布置它的两个子部件:

谈判是这样的:
- 小部件:”嘿,家长,我的限制是什么?“
- 家长:”你的宽度必须在
80
到300
像素之间,高度必须在30
到85
像素之间。“ - 小部件:”嗯,既然我想要
5
个像素的填充,那么我的孩子最多可以有290
个像素的宽度和75
个像素的高度。“ - 小部件:“嘿,第一个孩子,你的宽度必须在
0
到290
像素之间,高度必须在0
到75
像素之间。” - 第一个孩子:“好的,那我希望宽
290
像素,高20
像素。” - 小部件:“嗯,因为我想把我的第二个孩子放在第一个孩子下面,所以我的第二个孩子只剩下
55
像素的高度。” - 小部件:“嘿 老二,你的宽度必须在
0
到290
之间,高度必须在0
到55
之间。” - 第二个孩子:“好的,我希望宽
140
像素,高30
像素。” - 小部件:“很好。我的第一个孩子的位置是
x:5
和y:5
,我的第二个孩子的位置是x:80
和y:25
。” - 小部件:“嘿,家长,我决定我的尺寸为
300
像素宽,60
像素高。”
1、限制
由于上面提到的布局规则,Flutter的布局引擎有几个重要的限制:
- 小部件只能在其父级刚给定稿的约束范围内决定自己的大小。这意味着小部件通常不能有任何它想要的大小。
- 小部件无法知道也无法决定自己在屏幕的中的位置,因为是小部件的父级决定了小部件的位置。
- 由于父级的大小和位置反过来也取决于它自己的父级,因此不在考虑整个树的情况下不可能精确定义任何小部件的大小和位置。
- 如果一个子项想要与其父项不同的尺寸,而父项没有足够的信息来对其它,那么该子项的尺寸可能会被忽略。定义对齐方式时要具体。
1.1、例子
下面针对上述有29个例子,请客官们慢慢细读,读完了就对Contraints有了进一步的了解。
1.1.1、示例1

Container(color: red)
屏幕是Container
的父级,它强制Container
与屏幕大小完全相同。
所以Container
会填满屏幕并将其涂成红色。
1.1.2、示例2

Container(width: 100, height: 100, color: red)
红色的Container
想要100x100
,但它不能,因为屏幕强制它与屏幕大小完全相同。
所以容器填满了全屏。
1.1.3、示例3

Center(child: Container(width: 100, height: 100, color: red),
)
屏幕强制Center
与屏幕大小完全相同,因此Center会填满屏幕。
Center
告诉Container
它可以是它想要的任何大小,但不能大于屏幕。现在Contaiiner
确实可以是100x100
。
1.1.4、示例4

Align(alignment: Alignment.bottomRight,child: Container(wiidth: 100, height: 100, color: red)
),
这与前面的示例不同,它使用Align
而不是Center
。