一、Flutter 布局核心原则
- 父传约束,子定大小:父组件告诉子组件最大/最小宽高,子组件在范围内决定自身大小。
- 父组件大小 = 子组件大小 + 布局规则,大部分布局组件自身不固定大小。
- 所有组件行为只分三类:可设置宽高、父随子变、子撑满父。
二、Row / Column 主轴大小规则(最重要)
- 默认情况(不写 mainAxisSize)
- 主轴默认:MainAxisSize.max
- Row 宽度 / Column 高度 = 撑满父组件
- 设置 mainAxisSize: MainAxisSize.min
- 主轴大小 = 刚好包裹所有子组件
- 父组件大小随子组件变化
- 交叉轴规则(永远记住)
- Row 的高度、Column 的宽度 → 默认撑满父组件
三、哪些组件可以直接设置宽高?
以下组件支持 width / height ,能固定大小:
- Container
- SizedBox
- ConstrainedBox
- Image
- FractionallySizedBox
Text、Icon、Row、Column、Center、Align 不能直接设置宽高,必须套外层容器。
四、哪些组件父随子变(收缩包裹)?
不设置宽高时,父组件大小 = 子组件大小:
- Row(mainAxisSize: min)
- Column(mainAxisSize: min)
- Stack(无定位子组件)
- Wrap
- Text
- Icon
- Card
- ListTile
- Padding
- Container(有子组件、无宽高)
五、哪些组件子撑满父(自动填满)?
不设置宽高时,子组件自动撑满父组件:
- Center
- Align
- Expanded(必须在 Row/Column 内)
- Flexible(必须在 Row/Column 内)
- SizedBox(width: double.infinity)
- Container(设置 color/decoration 时)
- FractionallySizedBox
六、不设置宽高时,各组件大小如何确定?
- 基础容器
- Container
- 有子组件 → 包裹子组件
- 无子组件 → 宽高=0
- 加颜色/装饰 → 撑满父
- SizedBox
- 不写宽高 → 宽高=0
- Padding
- 大小 = 子组件 + padding
- 弹性布局
- Row
- 主轴:默认撑满父;min 则包裹子
- 交叉轴:撑满父
- Column
- 同上
- Expanded / Flexible
- 强制占满 Row/Column 剩余空间
- 对齐组件
- Center → 撑满父,子居中
- Align → 撑满父,子按对齐方式摆放
- 层叠布局
- Stack
- 无定位子组件 → 大小 = 最大子组件
- 有定位子组件 → 大小 = 父组件约束
- 内容组件
- Text → 大小由文字内容决定
- Icon → 固定默认大小(24×24)
七、高频布局坑点(必看)
- Row 里面直接放长文本会溢出
- 原因:Row 主轴无限,文本无限,冲突
- 解决:套 Expanded 或 Flexible
- Container 不加 child 会看不见
- 原因:无 child 且无宽高 → 大小为 0
- Expanded 只能放在 Row/Column/Flex 里
- 放别的地方直接报错
- Stack 未定位子组件会撑满 Stack
- 想让它自适应 → 套 Center/Align/Container
八、一句话速记
- 能设宽高:Container、SizedBox
- 父随子变:Row(min)、Column(min)、Stack、Wrap、Text
- 子撑满父:Center、Align、Expanded、Container(带颜色)
- Row/Column 主轴:默认撑满父,min 才包裹