【flutter】Flutter 布局约束
文章目录
-
一:Flutter布局过程
-
- 1.1 布局过程
- 1.2widget分类
-
二:Flutter 布局约束与常见 Widgets 对应解析
-
- 1. 紧约束(Tight Constraints )size==
-
定义
- 常用组件
- 示例说明
-
示例
-
2. 宽松约束(Loose Constraints)size<=
-
- 定义
- 常见 Widgets
- 示例
-
3. 无界约束(Unbounded Constraints)
-
- 定义
- 常见 Widgets
- 注意
- 示例
-
4. 固定范围约束(Tightened Constraints)
-
- 定义
- 常见 Widgets
- 示例
-
5. 松散约束但有优先级的约束
-
- 定义
- 常见 Widgets
- 示例
-
6. 自定义约束(Custom Constraints)
-
- 定义
- 常见 Widgets
-
总结表格
-
- 1. 紧约束(Tight Constraints )size==

一:Flutter布局过程
Flutter 中有两种布局模型:
- 采用RenderBox库实现的盒模型布局。
- 利用Sliver (RenderSliver)实现按需加载列表的布局方案。
这两种模型的布局过程都一样, 如下所示:
首先,在父组件中定义BoxConstraints并将其发送给子组件;BoxConstraints are passed from parent to child.
然后,在子组件中获取父组件的尺寸信息并将其发送给父组件;sizes information is retrieved by the child and sent back to the parent.
最终由父级组件确定子组件的位置;the position of the child is ultimately determined by its parent.
1.1 布局过程
Widget 可以通过其 父级 获取自身的限制范围。具体来说,约束由4种浮点数集合组成:包括最大和最小宽度以及最大和最小高度;此外,在这些参数中还包括可选的偏移量设置。
随后
然后,在 widget 的层次上将依次对它的子级元素 children 进行布局安排。(沿着 x 轴和 y 轴的方向分别进行)
最后将使 widget 向上层 widget 传递其大小信息并考虑这些原始限制
1.2widget分类
总体而言,box主要可分为三种类型:一种是尽量占据最大空间;另一种是与子节点保持一致的空间布局;第三种是按照指定尺寸进行布局。Container组件会根据不同的参数自动调整布局策略,在无宽度设置时会尽可能占据最大可用空间;而当设定宽度时,则会严格遵守该参数值进行排版安排。此外,在Row组件和Column组件(Flex系列组件)中也会根据其特定限制进行相应的空间分配。
二:Flutter 布局约束与常见 Widgets 对应解析
BoxConstraints 是 Flutter 布局系统的关键组件之一,在设定父组件与子组件的尺寸关系方面发挥重要作用。具体来说,按照约束类型划分,我们可以将其分为几种不同的类别,并根据需求选择合适的 Widgets 以实现相应的布局效果。
//BoxConstraints的定义
const BoxConstraints({
this.minWidth = 0.0, //最小宽度
this.maxWidth = double.infinity, //最大宽度
this.minHeight = 0.0, //最小高度
this.maxHeight = double.infinity //最大高度
})
/// Creates box constraints that is respected only by the given size.
BoxConstraints.tight(Size size)
: minWidth = size.width,
maxWidth = size.width,
minHeight = size.height,
maxHeight = size.height;
/// Creates box constraints that forbid sizes larger than the given size.
BoxConstraints.loose(Size size)
: minWidth = 0.0,
maxWidth = size.width,
minHeight = 0.0,
maxHeight = size.height;
/// Creates box constraints that expand to fill another box constraints.
///
/// If width or height is given, the constraints will require exactly the
/// given value in the given dimension.
const BoxConstraints.expand({
double? width,
double? height,
}) : minWidth = width ?? double.infinity,
maxWidth = width ?? double.infinity,
minHeight = height ?? double.infinity,
maxHeight = height ?? double.infinity;
1. 紧约束(Tight Constraints )size==
定义
- 父组件为子组件配置了必要的尺寸要求,并通过条件式子
minWidth == maxWidth$和`minHeight == maxHeight`确保所有子组件必须达到这些最小和最大尺寸。- 所有子组件都必须严格按照从父组件传递来的固定尺寸进行配置,并且无法自行调整或更改其尺寸大小。
常见 Widgets
- W肌肉块:确保子组件具有固定的宽高。
- 当设置宽度和高度时,则Container会迫使子组件保持特定尺寸。
- 按固定比率设定宽高比:确保子组件的比例一致。
- 当处于无界约束时,LimitedBox设定最大宽度和高度限制。
示例
SizedBox(
width: 100,
height: 100,
child: Container(color: Colors.red),
)
Center(
child:
AspectRatio(
aspectRatio: controller!.value.aspectRatio,
child: VideoPlayer(controller!),
),
);
2. 宽松约束(Loose Constraints)size<=
定义
- 父组件支持子组件灵活配置大小,并受限于 maxWidth 和 maxHeight。
- 通常 minWidth 和 minHeight 设为 0 ,形成较为宽泛的限制条件。
常见 Widgets
- Center选项中设置自定义尺寸(非强制性)。
- Align功能则支持自定义尺寸与定位设置。
- Padding选项会施加内边距控制,在设计上提供适度空间。
- UnconstrainedBox属性则提供灵活的空间管理方案。
示例
Center(
child: Container(
color: Colors.red,
width: 100,
height: 100,
),
)
3. 无界约束(Unbounded Constraints)
定义
- 父组件不给子组件设定宽度或高度上限(即通过
maxWidth = double.infinity$或maxHeight = double.infinity$来实现无限制)。- 这样的约束可能会带来问题, 因为很多子组件都需要明确的宽高比例才能进行有效的布局安排。
常见 Widgets
- ListView 和 ConstraintLayout:支持在滚动方向上的无界滚动(如垂直滚动时宽度不受限,在水平滚动时高度不受限)。
- Row 和 Column(沿主轴方向):确保子组件在此方向上不存在空间限制。
- UnconstrainedBox:传递这种无界约束但同时施加额外限制以防止布局失败。
注意
- 无界约束下,如果子组件未显式指定宽高,可能会导致报错。
示例
ListView(
children: [
Container(
height: 100,
color: Colors.red,
),
],
)
4. 固定范围约束(Tightened Constraints)
定义
父组件为子组件设定尺寸范围,在 minWidth/maxWidth 和 minHeight/maxHeight 之间确定具体大小。
常见 Widgets
- ConstrainedBox:对子组件施加额外尺寸约束(支持最小和最大值范围)。
- OverflowBox:不受父组件尺寸限制。
- FractionallySizedBox:根据父组件尺寸的比例来限定子组件大小。
- IntrinsicHeight 和 IntrinsicWidth:通过限定子组件大小来适应固有的宽度和高度。
示例
ConstrainedBox(
constraints: BoxConstraints(
minWidth: 50,
maxWidth: 150,
minHeight: 50,
maxHeight: 150,
),
child: Container(color: Colors.red),
)
5. 松散约束但有优先级的约束
定义
- 特殊类型的限制包括基于父组件空间比例计算子组件大小以及优化子组件内容等操作。
- 子组件在父组件空间中具有高度的灵活性,在满足优先级的情况下可自由配置其尺寸和布局。
常见 Widgets
- Dynamic allocation: The remaining space is allocated based on the
flexattribute. - Forced layout: Sub-components are forced to fill up the remaining space.
- Proportional allocation: Sub-components occupy specific proportions of the remaining space.
- Height adjustment: The sub-components' height is adjusted to match the content.
- Width adjustment: The sub-components' width is adjusted to match the content.
示例
Row(
children: [
Flexible(
child: Container(color: Colors.red),
),
Expanded(
child: Container(color: Colors.blue),
),
],
)
6. 自定义约束(Custom Constraints)
定义
- 自定义约束条件由开发人员在 CustomMultiChildLayout 以及自定义的RenderBox 中实现。
- 开发人员需要自行计算并提供给 BoxConstraints.
常见 Widgets
- CustomMultiChildLayout:主要用于处理复杂且多样的组件排版需求。
- Stack 和 Positioned:能够管理子组件的排列方式与尺寸设置。
- FittedBox:遵循适配策略(包括但不限于缩放、填充以及弹性布局等适配策略元素)。
总结表格
| 约束类型 | 定义 | 常见 Widgets |
|---|---|---|
| 严格约束 | 子组件必须使用固定尺寸 | SizedBox, Container, AspectRatio |
| 宽松约束 | 子组件可以自由选择尺寸 | Center, Align, Padding |
| 无界约束 | 子组件大小无限制 | ListView, Row, Column, UnconstrainedBox |
| 固定范围约束 | 子组件在指定范围内调整大小 | ConstrainedBox, OverflowBox, FractionallySizedBox |
| 动态约束 | 子组件按比例或剩余空间调整大小 | Flexible, Expanded, IntrinsicHeight |
| 自定义约束 | 开发者手动实现约束规则 | CustomMultiChildLayout, Stack, FittedBox |
通过深入掌握此类约束约束类型以及配套的应用程序组件,你能够更加高效地设计出复杂的Flutter布局系统。
