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),
],
)
);
}
}
效果图如下:
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 易语言 —— 开山篇