1113 字
6 分钟
flutter之flutter布局

参考链接#

布局——Flutter官方文档

布局结构#

在下面的示例中,下面截图显示三个带标签的图标

下面这张截图包括行和列的可视化布局。这张图中,debugPaintSizeEnabled 被设置为 true,因此可以看到可视化布局。

以下是上方示例的 widget 树示意图:

横向纵向排列#

Row 和 Column布局示例很像React中ant design,只不过flutter中的Row 和 Column适用于不一样的主题

  • Row 和 Column 是两种最常用的布局模式。

  • Row 和 Column 每个都有一个子 widget 列表。

  • 一个子 widget 本身可以是 Row、Column 或其他复杂 widget。

  • 可以指定 Row 或 Column 如何在垂直和水平方向上对齐其子项。

  • 可以拉伸或限制特定的子 widget。

  • 可以指定子 widget 如何占用 Row 或 Column 的可用空间。

布局设计示例:

flutter也有更多关于排列而已的替代方案:ListTitleListView

MainAxisAlignment#

MainAxisAlignment是用于横向纵向两种排列布局的类(依赖于不一样的widget,通常是作为一些widget的参数),有多个不场景的参数。下面一些例子,我主要为横向的布局提供示例,纵向只提供一个示例,因为逻辑原理一样。

MainAxisAlignment.spaceEvenly#

MainAxisAlignment.spaceEvenly是轴心居中,但是均匀占用空间

import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
title: 'Shopping List',
home: Scaffold(
appBar: AppBar(title: Text('Shopping List')),
body: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Image.asset('assets/imgs/pic1.png'),
Image.asset('assets/imgs/pic2.png'),
Image.asset('assets/imgs/pic3.png'),
],
),
),
));
}

下面是纵向的布局,逻辑原理跟横向是相同的

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
debugPaintSizeEnabled = true;
runApp(MaterialApp(
title: 'Shopping List',
home: Scaffold(
appBar: AppBar(title: Text('Shopping List')),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Image.asset('assets/imgs/pic1.png', bundle: null),
const Image(image: AssetImage('assets/imgs/pic2.png')),
Image.asset('assets/imgs/pic3.png')
],
),
),
));
}

MainAxisAlignment.center#

MainAxisAlignment.center仅是轴心居中,左右会自动分配一样的剩余空间

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
debugPaintSizeEnabled = true;
runApp(MaterialApp(
title: 'Shopping List',
home: Scaffold(
appBar: AppBar(title: Text('Shopping List')),
body: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset('assets/imgs/pic1.png', bundle: null),
const Image(image: AssetImage('assets/imgs/pic2.png')),
Image.asset('assets/imgs/pic3.png')
],
),
),
));
}

MainAxisAlignment.start#

MainAxisAlignment.end#

MainAxisAlignment.spaceAround#

MainAxisAlignment.spaceAround轴心居中,并会使得元素之间的间隔变大,但是左右剩余空间会变小。下面是两种不同的分辨率

MainAxisAlignment.spaceBetween#

MainAxisAlignment.spaceBetween轴心居中,左右不保留空间,间隔平均分配。下面是两种不一样的分辨率

CrossAxisAlignment.start#

当你为Row配置MainAxisAlignment.spaceEvenly时,其实默认能配置了CrossAxisAlignment.center,这是一个默认值,你即使不明确设置一样为会在设置。

当我们同时设置CrossAxisAlignment.start,会发生什么变化呢,官方对这个参数解释是:将子元素放置为起始边与横轴的起始边对齐

其实我也现在才发现,行高是以图片最大的那个设置

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
debugPaintSizeEnabled = true;
runApp(MaterialApp(
title: 'Shopping List',
home: Scaffold(
appBar: AppBar(title: Text('Shopping List')),
body: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Image.asset('assets/imgs/pic1.png', bundle: null),
const Image(image: AssetImage('assets/imgs/pic2.png')),
Image.asset('assets/imgs/pic3.png')
],
),
),
));
}

前面的示例其实我没有说过,但是实际上我的图片大小是不一样,只是因为不太容易看出来,现在设置CrossAxisAlignment.start,代表横向布局中,元素是紧贴上边缘的,大小不一样会很明显

CrossAxisAlignment.end#

CrossAxisAlignment.start相反的CrossAxisAlignment.end,代表横向布局中,元素是紧贴下边缘的

Row 不支持CrossAxisAlignment.baseline#

CrossAxisAlignment.baseline似乎用于,横向布局中文本的水本对齐,但是在ROW中如果指定了这个参数,会报错

CrossAxisAlignment.stretch#

这个参数还没有看出来什么用途,注释是这样解释的这会导致传递给子元素的约束在横轴上变得紧密

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
debugPaintSizeEnabled = true;
runApp(MaterialApp(
title: 'Shopping List',
home: Scaffold(
appBar: AppBar(title: Text('Shopping List')),
body: Row(
// mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Image.asset('assets/imgs/pic1.png', bundle: null),
const Image(image: AssetImage('assets/imgs/pic2.png')),
Image.asset('assets/imgs/pic3.png')
],
),
),
));
}

图中黄白交叉的内容,是表示内容已经超出右侧屏幕。而且已经超出1458px

调整widget的大小#

当图片大小太时,会明显超出屏幕,可以Expanded类来灵活调节,下面你可以看看下面两个分辨率下的布局,在大的分辨率中,会使图片使用更大宽高,或者变成原始图片的宽高。

也许你想要一个 widget 占用的空间是兄弟项的两倍。为了达到这个效果,可以使用 Expanded widget 的 flex 属性,这是一个用来确定 widget 的弹性系数的整数。默认的弹性系数为 1,以下代码将中间图像的弹性系数设置为 2: 感觉加一个动画就能变成画廊了

flutter之flutter布局
https://iszengmh.pages.dev/posts/flutter之flutter布局/
作者
Rise Zeng
发布于
2026-04-23
许可协议
CC BY-NC-SA 4.0