学习内容:
线性布局:
Row(水平排列)、Column(垂直排列)容器组件:
Container(控制宽高、背景色、边距)实践任务:
用
Column做一个页面:顶部标题、中间图片、底部两个按钮(水平排列用Row)给容器加边距(
margin)、内边距(padding)、背景色
一、前置知识:Flutter布局的核心概念※
1. 布局的本质※
通过“父组件”约束“子组件”的位置和大小,子组件在约束范围内排列
2. 主轴与交叉轴※
主轴:组件排列的方向(Row的主轴是水平方向,Column的主轴是垂直方向)
交叉轴:与主轴垂直的方向(Row的交叉轴是垂直方向,Column的交叉轴是水平方向)
3. 约束传递※
父组件给子组件设置约束(如最大宽高),子组件根据约束确定自身大小,再进行排列
二、线性布局:Row(水平排列)※
1. 核心作用※
将子组件按水平方向依次排列,是实现横向布局(如导航栏、按钮组)的核心组件。
2. 核心属性※
| 属性名 | 作用 | 常用值(以Row为例) |
| children | 子组件列表(必须传,可以放多个Widget) | [Text('A'), Text('B), …] |
| mainAxisAlignment | 主轴对齐方式(水平方向) | MainAxisAlignment.start(默认左对齐)、center(居中)、end(右对齐)、spaceBetween(两端对齐,中间均匀分布)、spaceAround(均匀分布,两侧留空)、spaceEvenly(完全均匀分布) |
| crossAxisAlignment | 交叉轴对齐方式(垂直方向) | CrossAxisAlignment.center(默认居中)、start(顶部对齐)、end(底部对齐)、stretch(拉伸填满交叉轴) |
| mainAxisSize | 主轴占用空间(水平方向宽度) | MainAxisSize.max(默认,占满父组件)、min(仅占用子组件总宽度) |
| children | 子组件列表 | 任意Widget组合 |
3. 代码示例※
(1)示例1:基础Row(默认对齐)※
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Row基础示例')),
body: Padding(
padding: const EdgeInsets.all(16), // 页面内边距,避免组件贴边
child: Row(
// 默认:mainAxisAlignment=start(左对齐),crossAxisAlignment=center(垂直居中)
children: [
// 子组件1:红色容器
Container(width: 80, height: 80, color: Colors.red),
// 水平边距组件
const SizedBox(width: 16),
// 子组件2:蓝色容器
Container(width: 80, height: 80, color: Colors.blue),
const SizedBox(width: 16),
// 子组件3:绿色容器
Container(width: 80, height: 80, color: Colors.green)
],
),
),
),
);
}
}- 运行效果:

(2)示例2:主轴对齐(mainAxisAlignment)※
- 修改示例1的Row属性,测试不同主轴对齐方式
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, // 两端对齐,中间均匀分布
children: [
Container(width: 80, height: 80, color: Colors.red),
Container(width: 80, height: 80, color: Colors.blue),
Container(width: 80, height: 80, color: Colors.green),
],
)- 运行效果:

- 常见对齐效果
- start:左对齐(默认)
- center:水平居中
- end:右对齐
- spaceBetween:左右两侧贴边,中间组件均匀分布
- spaceAround:组件之间间距相等,两侧留一半间距
- spaceEvenly:组件之间和两侧间距完全相等
(3)示例3:交叉轴对齐(crossAxisAlignment)※
- 让子组件高度不同,测试交叉轴对齐:
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end, // 垂直底部对齐
children: [
Container(width: 80, height: 60, color: Colors.red), // 高度60
const SizedBox(width: 16),
Container(width: 80, height: 80, color: Colors.blue), // 高度80
const SizedBox(width: 16),
Container(width: 80, height: 100, color: Colors.green), // 高度100
],
)- 运行效果:

- 重点:crossAxisAlignment:stretch会让所有组件拉伸到与Row交叉轴(垂直方向)同高(需确保Row的高度足够)
(4)示例4:mainAixsSize控制主轴占用空间※
Row(
mainAxisSize: MainAxisSize.min, // 仅占用子组件总宽度(不占满屏幕)
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(width: 80, height: 80, color: Colors.red),
const SizedBox(width: 16),
Container(width: 80, height: 80, color: Colors.blue),
],
)- 运行效果

4. 常见问题:Row布局溢出(Overflow)※
- 当子组件总宽度超过父组件宽度时,会出现黄色警告条(溢出)
// 错误示例:3个120px的容器+间距,总宽度=120+16+120+16+120=392px,超过手机屏幕宽度(约360px)
Row(
children: [
Container(width: 120, height: 80, color: Colors.red),
const SizedBox(width: 16),
Container(width: 120, height: 80, color: Colors.blue),
const SizedBox(width: 16),
Container(width: 120, height: 80, color: Colors.green),
],
)- 运行效果

解决办法:用SingleChildScrollView包裹Row,实现水平滚动
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text('Row基础示例')), body: Padding( padding: const EdgeInsets.all(16), // 页面内边距,避免组件贴边 child: SingleChildScrollView( scrollDirection: Axis.horizontal, // 水平滚动 child: Row( // 默认:mainAxisAlignment=start(左对齐),crossAxisAlignment=center(垂直居中) children: [ // 子组件1:红色容器 Container(width: 120, height: 80, color: Colors.red), // 水平边距组件 const SizedBox(width: 16), // 子组件2:蓝色容器 Container(width: 120, height: 80, color: Colors.blue), const SizedBox(width: 16), // 子组件3:绿色容器 Container(width: 120, height: 100, color: Colors.green) ], ), ), ), ), ); } }运行效果

三、线性布局:Column(垂直排列)※
1. 核心作用※
将子组件按垂直方向依次排列,是实现纵向布局(如:页面主体、列表项内部结构)的核心组件。
2. 核心属性(与Row一致,仅主轴/交叉轴方向不同)※
四、容器组件Container※
1. 核心作用※
Container是Flutter中最常用的“容器组件”,用于包裹子组件并控制其:
- 大小(宽高)
- 背景(颜色、图片、渐变)
- 边距(内边距padding、外边距margin)
- 装饰(边框、圆角、阴影)
- 定位(配合Stack布局时)
2. 核心属性※
| 属性名 | 作用 | 示例值 |
| width/height | 容器宽高(固定值) | width: 200、height: 150 |
| color | 背景色(与decoration互斥,不能同时设置) | color: Colors.yellow |
| padding | 内边距(容器与子组件之间的间距) | padding: EdgeInset.all(16)、 EdgeInsets.symmetric(horizontal: 12, vertical: 8) |
| margin | 外边距(容器与其他组件之间的间距) | margin: EdgeInsets.only(left: 10, top: 20) |
| decoration | 装饰(边框、圆角、阴影、背景图片等) | BoxDecoration(…) |
| alignment | 子组件在容器内的对齐方式 | Alignment.center、Alignment.bottomRight |
| constraints | 容器的约束(最小/最大宽高) | BoxConstraints(minWidth: 100, maxHeight: 200) |
五、综合实战※
- 需求:
- 顶部是标题栏(AppBar)
- 主体式个人信息卡片(Column垂直排列)
- 头像(圆形Container)
- 姓名、昵称(文本、水平居中)
- 功能按钮栏(Row水平排列,3个按钮)
- 卡片有边框、圆角、阴影,整体居中显示
- 代码参考
import 'package:flutter/material.dart';
void main() => runApp(const InfoCard());
class InfoCard extends StatelessWidget {
const InfoCard({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('个人信息卡片'),
centerTitle: true, // 标题居中
),
body: Center(
child: Container(
width: 320,
padding: const EdgeInsets.all(20),
margin: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: Colors.grey.withValues(alpha: 0.3),
spreadRadius: 1,
blurRadius: 8,
offset: const Offset(0, 3)
)
],
border: Border.all(color: Colors.blue[100]!, width: 1)
),
// 卡片内部:垂直排列
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
width: 100,
height: 100,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: const DecorationImage(
image: NetworkImage("https://upyun.askrabbit.net/avatar.png") ,
fit: BoxFit.cover
),
border: Border.all(color: Colors.yellow, width: 3)
),
),
const SizedBox(height: 16),
const Text(
'清遥',
style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
const Text(
'@安全研发工程师',
style: TextStyle(color: Colors.yellow, fontSize: 16),
),
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Column(
children: const [
Text('32', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
Text('学习天数', style: TextStyle(color: Colors.blue, fontSize: 14))
],
),
Column(
children: const [
Text('8', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
Text('已学习课程', style: TextStyle(color: Colors.blue, fontSize: 14))
],
),
Column(
children: const [
Text('3', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
Text('收藏', style: TextStyle(color: Colors.blue, fontSize: 14))
],
)
],
),
const SizedBox(height: 16),
Container(
width: double.infinity,
height: 44,
decoration: BoxDecoration(
color: Colors.pink,
borderRadius: BorderRadius.circular(8)
),
child: const Center(
child: Text(
'关注+',
style: TextStyle(color: Colors.white, fontSize: 16),
),
),
)
],
),
),
),
),
);
}
}- 运行效果
