Skip to content

线性布局

线性布局是最常用的布局方式,让子组件沿水平方向(Row)或垂直方向(Column)排列。

Column — 垂直排列

Column 让子组件从上到下排列。

常用属性

dart
Column({
  MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,  // 主轴对齐(垂直)
  MainAxisSize mainAxisSize = MainAxisSize.max,                  // 主轴大小
  CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center, // 交叉轴对齐(水平)
  TextDirection? textDirection,
  VerticalDirection verticalDirection = VerticalDirection.down,
  List<Widget> children = const <Widget>[],
})

基本用法

dart
import 'package:flutter/material.dart';

class ColumnBasicExample extends StatelessWidget {
  const ColumnBasicExample({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Column 基本用法')),
      // ─── ★ Column 垂直排列 ──────────────
      body: const Column(
        children: [
          Text('第一行'),
          Text('第二行'),
          Text('第三行'),
        ],
      ),
      // ─── ☆ Column 垂直排列 ──────────────
    );
  }
}

主轴对齐(mainAxisAlignment)

dart
import 'package:flutter/material.dart';

class MainAxisAlignmentExample extends StatelessWidget {
  const MainAxisAlignmentExample({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('主轴对齐')),
      body: Column(
        // ─── ★ 主轴对齐方式 ──────────────
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        // ─── ☆ 主轴对齐方式 ──────────────
        children: const [
          Text('第一行'),
          Text('第二行'),
          Text('第三行'),
        ],
      ),
    );
  }
}

各值效果说明:

效果
MainAxisAlignment.start从顶部开始(默认)
MainAxisAlignment.center居中
MainAxisAlignment.end底部
MainAxisAlignment.spaceEvenly等间距(含两端)
MainAxisAlignment.spaceAround等间距(两端减半)
MainAxisAlignment.spaceBetween两端贴边,中间等间距

交叉轴对齐(crossAxisAlignment)

dart
import 'package:flutter/material.dart';

class CrossAxisAlignmentExample extends StatelessWidget {
  const CrossAxisAlignmentExample({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('交叉轴对齐')),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start, // 尝试替换为 center / end / stretch
        children: const [
          Text('短文本'),
          Text('这是一段比较长的文本'),
          Text('中等'),
        ],
      ),
    );
  }
}

各值效果说明:

效果
CrossAxisAlignment.start左对齐
CrossAxisAlignment.center居中(默认)
CrossAxisAlignment.end右对齐
CrossAxisAlignment.stretch拉伸填满

Row — 水平排列

Row 让子组件从左到右排列。属性与 Column 完全相同,只是主轴方向不同(水平 vs 垂直)。

基本用法

dart
import 'package:flutter/material.dart';

class RowBasicExample extends StatelessWidget {
  const RowBasicExample({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Row 基本用法')),
      body: const Row(
        children: [
          Icon(Icons.star),
          SizedBox(width: 8),
          Text('收藏'),
        ],
      ),
    );
  }
}

对齐方式

dart
Row(
  mainAxisAlignment: MainAxisAlignment.center,   // 水平居中
  crossAxisAlignment: CrossAxisAlignment.center, // 垂直居中
  children: const [Text('居中内容')],
)

常见模式

dart
import 'package:flutter/material.dart';

class RowPatternsExample extends StatelessWidget {
  const RowPatternsExample({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Row 常见模式')),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          // 左右分布(如:标题 + 操作按钮)
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              const Text('标题'),
              IconButton(icon: const Icon(Icons.more_vert), onPressed: () {}),
            ],
          ),
          const SizedBox(height: 16),

          // 图标 + 文字 + 间距
          Row(
            children: [
              Icon(Icons.location_on, size: 16, color: Colors.grey[600]),
              const SizedBox(width: 4),
              Text('北京市', style: TextStyle(color: Colors.grey[600])),
            ],
          ),
        ],
      ),
    );
  }
}

Expanded / Flexible — 弹性分配

当需要让子组件按比例分配剩余空间时,使用 ExpandedFlexible

Expanded — 占满剩余空间

dart
import 'package:flutter/material.dart';

class ExpandedExample extends StatelessWidget {
  const ExpandedExample({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Expanded 示例')),
      body: Row(
        children: [
          Container(width: 50, color: Colors.red),
          Expanded(
            child: Container(color: Colors.blue, child: const Center(child: Text('剩余空间'))),
          ),
        ],
      ),
    );
  }
}

flex 参数 — 按比例分配

dart
import 'package:flutter/material.dart';

class FlexExample extends StatelessWidget {
  const FlexExample({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Flex 按比例分配')),
      body: Row(
        children: [
          Expanded(
            flex: 1,
            child: Container(color: Colors.red, child: const Center(child: Text('1份'))),
          ),
          Expanded(
            flex: 2,
            child: Container(color: Colors.blue, child: const Center(child: Text('2份'))),
          ),
        ],
      ),
    );
  }
}
// 红色占 1/3,蓝色占 2/3

Expanded vs Flexible

ExpandedFlexible
行为必须填满剩余空间可以不填满(根据子组件大小)
fit 参数无(相当于 FlexFit.tightFlexFit.loose(默认)/ FlexFit.tight
典型场景列表项左右分布子组件有固定大小时
dart
import 'package:flutter/material.dart';

class ExpandedVsFlexible extends StatelessWidget {
  const ExpandedVsFlexible({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Expanded vs Flexible')),
      body: Column(
        children: [
          const Text('Expanded:子组件被强制拉伸'),
          Row(
            children: [
              Expanded(child: Container(color: Colors.red[100], child: const Text('短'))),
              Expanded(child: Container(color: Colors.blue[100], child: const Text('比较长的文字'))),
            ],
          ),
          const SizedBox(height: 16),
          const Text('Flexible(loose):子组件不被强制拉伸'),
          Row(
            children: [
              Flexible(child: Container(color: Colors.red[100], child: const Text('短'))),
              Flexible(child: Container(color: Colors.blue[100], child: const Text('比较长的文字'))),
            ],
          ),
        ],
      ),
    );
  }
}

Align / Center — 对齐

Center — 居中

CenterAlign 的特例,等价于 Alignment.center

dart
import 'package:flutter/material.dart';

class CenterExample extends StatelessWidget {
  const CenterExample({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: const Text('居中文字'),
      ),
    );
  }
}

Align — 任意位置对齐

dart
import 'package:flutter/material.dart';

class AlignExample extends StatelessWidget {
  const AlignExample({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Align(
        alignment: Alignment.topLeft,  // 尝试替换为 topRight / bottomCenter / Alignment(0.5, 0.5)
        child: Container(
          color: Colors.blue,
          padding: const EdgeInsets.all(16),
          child: const Text('对齐文字'),
        ),
      ),
    );
  }
}

常用对齐值

Alignment 常量位置
topLeft左上
topCenter上中
topRight右上
centerLeft左中
center正中
centerRight右中
bottomLeft左下
bottomCenter下中
bottomRight右下

Wrap — 自动换行

当子组件在主轴上放不下时,Wrap 会自动换行(类似 CSS 的 flex-wrap)。

基本用法

dart
import 'package:flutter/material.dart';

class WrapExample extends StatelessWidget {
  const WrapExample({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Wrap 自动换行')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Wrap(
          spacing: 8,        // 水平间距
          runSpacing: 8,     // 垂直间距(换行间距)
          alignment: WrapAlignment.start,
          children: const [
            Chip(label: Text('标签1')),
            Chip(label: Text('标签2')),
            Chip(label: Text('标签3')),
            Chip(label: Text('标签4')),
            Chip(label: Text('标签5')),
          ],
        ),
      ),
    );
  }
}

常用属性

属性说明默认值
direction排列方向Axis.horizontal
spacing主轴间距0.0
runSpacing交叉轴间距0.0
alignment主轴对齐WrapAlignment.start
crossAxisAlignment交叉轴对齐WrapCrossAlignment.start

Row 溢出 vs Wrap 自动换行

dart
import 'package:flutter/material.dart';

class OverflowVsWrap extends StatelessWidget {
  const OverflowVsWrap({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Row 溢出 vs Wrap 换行')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const Text('✅ Wrap 自动换行:', style: TextStyle(fontWeight: FontWeight.bold)),
            Wrap(
              spacing: 8,
              runSpacing: 8,
              children: [
                Container(width: 200, height: 50, color: Colors.red),
                Container(width: 200, height: 50, color: Colors.blue),
                Container(width: 200, height: 50, color: Colors.green),
              ],
            ),
            const SizedBox(height: 16),
            const Text('❌ Row 溢出报错(内容太多放不下),不要这样写!'),
          ],
        ),
      ),
    );
  }
}

线性布局速查

需求组件
垂直排列Column
水平排列Row
子组件占满剩余空间Expanded
子组件按比例分配Expanded(flex: n)
居中显示Center
任意位置对齐Align
自动换行Wrap
组件间间距SizedBox

下一步

基于 Flutter 官方文档整理