Flutter布局(1):线性布局(Row、Column)
所谓线性布局,即指沿水平或垂直方向排列子组件。Flutter 中通过Row和Column来实现线性布局。
主轴和纵轴
对于线性布局,有主轴和纵轴之分,如果布局是沿水平方向,那么主轴就是指水平方向,而纵轴即垂直方向;如果布局沿垂直方向,那么主轴就是指垂直方向,而纵轴就是水平方向。
一、Row组件
1.1 Row介绍
在 Flutter 中,Row是一个水平布局的小部件,用于将子控件沿着水平轴排列。它非常适合用来创建行式布局,如表单输入、按钮组、标签栏等。从源码中查看 Row的属性:
Row({
Key key,
MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start, // 主轴对齐方式
MainAxisSize mainAxisSize = MainAxisSize.max, // 水平方向尽可能大
CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center, // 交叉轴对齐方式
TextDirection textDirection, // 水平方向子widget的布局顺序(默认为系统当前Locale环境的文本方向(如中文、英语都是从左往右,而阿拉伯语是从右往左))
VerticalDirection verticalDirection = VerticalDirection.down, // 表示Row纵轴(垂直)的对齐方向
TextBaseline textBaseline, // 如果上面是baseline对齐方式,那么选择什么模式(有两种可选)
List<Widget> children = const <Widget>[],
})
1.2 基础用法
Row最基本的用法是将多个控件水平排列:
Row(
children: <Widget>[
Container(width: 50.0, height: 50.0, color: Colors.red),
Container(width: 50.0, height: 50.0, color: Colors.blue),
// ... 更多的控件
],
)
1.3 主轴对齐
Row的mainAxisAlignment属性用于控制子控件在主轴(水平轴)上的对齐方式,其是一个枚举类型,代码如下:
enum MainAxisAlignment {
// 将子控件放在主轴的开始位置
start,
// 将子控件放在主轴的结束位置
end,
// 将子控件放在主轴的中间位置
center,
// 将主轴空白位置进行均分,排列子元素,手尾没有空隙
spaceBetween,
// 将主轴空白区域均分,使中间各个子控件间距相等,首尾子控件间距为中间子控件间距的一半
spaceAround,
// 将主轴空白区域均分,使各个子控件间距相等
spaceEvenly,
}
1.4 交叉轴对齐
Row的crossAxisAlignment属性用于控制子控件在交叉轴(垂直轴)上的对齐方式,其是一个枚举类型,代码如下:
enum CrossAxisAlignment {
// 将子控件放在交叉轴的起始位置
start,
// 将子控件放在交叉轴的结束位置
end,
// 将子控件放在交叉轴的中间位置
center,
// 使子控件填满交叉轴
stretch,
// 将子控件放在交叉轴的上,并且与基线相匹配(不常用)
baseline,
}
1.5 间距和边距
Row的mainAxisSize属性决定了Row的大小是否应该占据所有可用空间:
Row(
mainAxisSize: MainAxisSize.max,
// ... 子控件
)
- 默认是
MainAxisSize.max,表示尽可能多的占用水平方向的空间,此时无论子widgets实际占用多少水平空间,Row的宽度始终等于水平方向的最大宽度; - 而
MainAxisSize.min表示尽可能少的占用水平空间,当子widgets没有占满水平剩余空间,则Row的实际宽度等于所有子widgets占用的的水平空间;
通过padding属性,可以为Row添加内边距:
Row(
padding: EdgeInsets.all(8.0),
// ... 子控件
)
1.6 子控件大小调整
使用flex属性来设置子控件在Row中的弹性比例:
Row(
children: <Widget>[
Expanded(
flex: 1,
child: Container(color: Colors.red),
),
Expanded(
flex: 2,
child: Container(color: Colors.blue),
),
],
)
1.7 实例
下面是一个使用Row创建水平布局的实例:
// ignore_for_file: prefer_const_constructors
import 'package:flutter/material.dart';
main(List<String> args) {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: MyHomeBody(),
),
);
}
}
class MyHomeBody extends StatelessWidget {
const MyHomeBody({super.key});
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
height: 500,
margin: EdgeInsets.all(10),
decoration: BoxDecoration(
border: Border.all(
color: Colors.black,
width: 1,
),
),
child:Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, // 主轴对齐方式:均匀分布
crossAxisAlignment: CrossAxisAlignment.center, // 交叉轴对齐方式:居中对齐
children: <Widget>[
Container(color: Colors.red, width: 60, height: 60),
Container(color: Colors.blue, width: 80, height: 80),
Container(color: Colors.green, width: 70, height: 70),
Container(color: Colors.orange, width: 100, height: 100),
],
)
);
}
}
效果图如下:

二、Column组件
2.1 Column介绍
在 Flutter 中,Column是一个垂直布局的小部件,用于将子控件沿着垂直轴排列。Column与Row相对,Row是水平布局,而Column则是垂直布局。它非常适合用来创建列式布局,如表单、列表项、导航栏等。从源码中查看Column的属性:
Column({
Key key,
MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
MainAxisSize mainAxisSize = MainAxisSize.max,
CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
TextDirection textDirection,
VerticalDirection verticalDirection = VerticalDirection.down,
TextBaseline textBaseline,
List<Widget> children = const <Widget>[],
})
2.2 基础用法
Column最基本的用法是将多个控件垂直排列:
Column(
children: <Widget>[
Container(height: 50.0, color: Colors.red),
Container(height: 50.0, color: Colors.blue),
// ... 更多的控件
],
)
属性基本都和Row的一致,所以下面就不赘述了,直接看实例。
2.3 实例
我们直接将Row的代码中Row改为Column,查看代码运行效果:
// ignore_for_file: prefer_const_constructors
import 'package:flutter/material.dart';
main(List<String> args) {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: MyHomeBody(),
),
);
}
}
class MyHomeBody extends StatelessWidget {
const MyHomeBody({super.key});
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
height: 500,
margin: EdgeInsets.all(10),
decoration: BoxDecoration(
border: Border.all(
color: Colors.black,
width: 1,
),
),
child:Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, // 主轴对齐方式:均匀分布
crossAxisAlignment: CrossAxisAlignment.center, // 交叉轴对齐方式:居中对齐
children: <Widget>[
Container(color: Colors.red, width: 60, height: 60),
Container(color: Colors.blue, width: 80, height: 80),
Container(color: Colors.green, width: 70, height: 70),
Container(color: Colors.orange, width: 100, height: 100),
],
)
);
}
}
效果图如下:


浙公网安备 33010602011771号