Flutter布局基础 #

一、布局原理 #

1.1 约束模型 #

Flutter使用约束向下传递、尺寸向上传递的布局模型:

text
父Widget                    子Widget
    │                           │
    │ 传递约束                   │
    │ (最小/最大宽高)            │
    │ ──────────────────────▶   │
    │                           │
    │ 返回尺寸                   │
    │ (实际宽高)                 │
    │ ◀──────────────────────   │
    │                           │

1.2 约束类型 #

dart
BoxConstraints({
  double minWidth = 0.0,
  double maxWidth = double.infinity,
  double minHeight = 0.0,
  double maxHeight = double.infinity,
})

BoxConstraints.tight(Size size)
BoxConstraints.loose(Size size)
BoxConstraints.expand({double? width, double? height})
BoxConstraints.tightFor({double? width, double? height})
BoxConstraints.tightForFinite({double? width, double? height})

1.3 布局规则 #

  1. 父Widget向子Widget传递约束
  2. 子Widget根据约束确定自己的尺寸
  3. 子Widget向父Widget返回尺寸
  4. 父Widget决定子Widget的位置

1.4 常见约束场景 #

场景 约束
无限制 0 ≤ width ≤ ∞, 0 ≤ height ≤ ∞
精确尺寸 width = 100, height = 100
最小尺寸 100 ≤ width ≤ ∞, 100 ≤ height ≤ ∞
最大尺寸 0 ≤ width ≤ 100, 0 ≤ height ≤ 100

二、单子Widget布局 #

2.1 Container #

dart
Container({
  AlignmentGeometry? alignment,
  EdgeInsetsGeometry? padding,
  Color? color,
  Decoration? decoration,
  double? width,
  double? height,
  BoxConstraints? constraints,
  EdgeInsetsGeometry? margin,
  Widget? child,
})

Container(
  width: 200,
  height: 100,
  padding: EdgeInsets.all(16),
  margin: EdgeInsets.all(8),
  decoration: BoxDecoration(
    color: Colors.blue,
    borderRadius: BorderRadius.circular(8),
  ),
  child: Text('Container'),
)

2.2 Padding #

dart
Padding(
  padding: EdgeInsets.all(16),
  child: Text('Padded'),
)

Padding(
  padding: EdgeInsets.only(left: 16, top: 8),
  child: Text('Partial Padding'),
)

Padding(
  padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
  child: Text('Symmetric Padding'),
)

2.3 Center #

dart
Center(
  child: Container(
    width: 100,
    height: 100,
    color: Colors.blue,
  ),
)

Center(
  widthFactor: 2.0,
  heightFactor: 2.0,
  child: Text('Centered with factor'),
)

2.4 Align #

dart
Align(
  alignment: Alignment.topRight,
  child: Text('Top Right'),
)

Align(
  alignment: Alignment(-0.5, 0.5),
  child: Text('Custom Alignment'),
)

Align(
  widthFactor: 2.0,
  heightFactor: 2.0,
  child: Text('Align with factor'),
)

2.5 FittedBox #

dart
FittedBox(
  fit: BoxFit.contain,
  child: Text('Fitted Text'),
)

FittedBox(
  fit: BoxFit.cover,
  alignment: Alignment.center,
  child: Container(
    width: 100,
    height: 50,
    color: Colors.blue,
  ),
)

2.6 AspectRatio #

dart
AspectRatio(
  aspectRatio: 16 / 9,
  child: Container(color: Colors.blue),
)

AspectRatio(
  aspectRatio: 1.0,
  child: Container(color: Colors.red),
)

2.7 ConstrainedBox #

dart
ConstrainedBox(
  constraints: BoxConstraints(
    minWidth: 100,
    maxWidth: 200,
    minHeight: 50,
    maxHeight: 100,
  ),
  child: Container(color: Colors.blue),
)

2.8 LimitedBox #

dart
ListView(
  children: [
    LimitedBox(
      maxWidth: 150,
      maxHeight: 150,
      child: Container(color: Colors.blue),
    ),
  ],
)

2.9 FractionallySizedBox #

dart
FractionallySizedBox(
  widthFactor: 0.5,
  heightFactor: 0.3,
  child: Container(color: Colors.blue),
)

FractionallySizedBox(
  alignment: Alignment.center,
  widthFactor: 0.8,
  child: Text('80% width'),
)

2.10 IntrinsicHeight & IntrinsicWidth #

dart
IntrinsicHeight(
  child: Row(
    children: [
      Container(width: 50, height: 100, color: Colors.red),
      Container(width: 50, height: 50, color: Colors.blue),
    ],
  ),
)

IntrinsicWidth(
  child: Column(
    children: [
      Container(width: 100, height: 50, color: Colors.red),
      Container(width: 50, height: 50, color: Colors.blue),
    ],
  ),
)

三、SizedBox #

3.1 固定尺寸 #

dart
SizedBox(
  width: 100,
  height: 100,
  child: Container(color: Colors.blue),
)

3.2 间距 #

dart
Column(
  children: [
    Text('Item 1'),
    SizedBox(height: 16),
    Text('Item 2'),
    SizedBox(height: 16),
    Text('Item 3'),
  ],
)

3.3 扩展 #

dart
SizedBox.expand(
  child: Container(color: Colors.blue),
)

SizedBox.fromSize(
  size: Size(100, 100),
  child: Container(color: Colors.red),
)

3.4 无限尺寸 #

dart
SizedBox(
  width: double.infinity,
  child: ElevatedButton(
    onPressed: () {},
    child: Text('Full Width Button'),
  ),
)

四、Spacer #

4.1 基本用法 #

dart
Row(
  children: [
    Text('Left'),
    Spacer(),
    Text('Right'),
  ],
)

4.2 设置比例 #

dart
Row(
  children: [
    Text('Left'),
    Spacer(flex: 2),
    Text('Middle'),
    Spacer(flex: 1),
    Text('Right'),
  ],
)

五、Transform #

5.1 平移 #

dart
Transform.translate(
  offset: Offset(10, 20),
  child: Container(
    width: 100,
    height: 100,
    color: Colors.blue,
  ),
)

5.2 旋转 #

dart
Transform.rotate(
  angle: 0.5,
  child: Container(
    width: 100,
    height: 100,
    color: Colors.blue,
  ),
)

5.3 缩放 #

dart
Transform.scale(
  scale: 1.5,
  child: Container(
    width: 100,
    height: 100,
    color: Colors.blue,
  ),
)

5.4 矩阵变换 #

dart
Transform(
  transform: Matrix4.identity()
    ..rotateZ(0.1)
    ..scale(1.2)
    ..translate(10.0, 20.0),
  alignment: Alignment.center,
  child: Container(
    width: 100,
    height: 100,
    color: Colors.blue,
  ),
)

六、Offstage #

6.1 基本用法 #

dart
Offstage(
  offstage: _isVisible,
  child: Container(
    width: 100,
    height: 100,
    color: Colors.blue,
  ),
)

七、Visibility #

7.1 基本用法 #

dart
Visibility(
  visible: _isVisible,
  child: Container(
    width: 100,
    height: 100,
    color: Colors.blue,
  ),
)

7.2 替换Widget #

dart
Visibility(
  visible: _isVisible,
  replacement: Container(
    width: 100,
    height: 100,
    color: Colors.grey,
  ),
  child: Container(
    width: 100,
    height: 100,
    color: Colors.blue,
  ),
)

7.3 保持状态 #

dart
Visibility(
  visible: _isVisible,
  maintainState: true,
  maintainAnimation: true,
  maintainSize: true,
  maintainInteractivity: false,
  child: Container(
    width: 100,
    height: 100,
    color: Colors.blue,
  ),
)

八、Overflow #

8.1 OverflowBox #

dart
Container(
  width: 100,
  height: 100,
  color: Colors.grey,
  child: OverflowBox(
    maxWidth: 200,
    maxHeight: 200,
    child: Container(
      width: 200,
      height: 200,
      color: Colors.blue,
    ),
  ),
)

8.2 SizedOverflowBox #

dart
SizedOverflowBox(
  size: Size(100, 100),
  child: Container(
    width: 200,
    height: 200,
    color: Colors.blue,
  ),
)

8.3 ClipRect #

dart
ClipRect(
  child: Container(
    width: 100,
    height: 100,
    color: Colors.grey,
    child: OverflowBox(
      maxWidth: 200,
      maxHeight: 200,
      child: Container(
        width: 200,
        height: 200,
        color: Colors.blue,
      ),
    ),
  ),
)

九、总结 #

9.1 布局Widget分类 #

类型 Widget
容器 Container、Padding、Center
尺寸约束 SizedBox、ConstrainedBox、LimitedBox
比例 AspectRatio、FractionallySizedBox
变换 Transform
可见性 Visibility、Offstage
溢出 OverflowBox、ClipRect

9.2 下一步 #

掌握了布局基础后,让我们学习 线性布局

最后更新:2026-03-28