2.Flutter开发
二.Flutter开发
1.环境搭建
先参考官方环境搭建文档 搭建完成基础环境后,还需要安装插件Awesome Flutter Snippets。
flutter 常用命令
# 创建新项目
flutter create my_app
# 创建项目(指定平台)
flutter create --platforms=android,windows my_app
# 运行项目
flutter run
# 运行并指定设备
flutter run -d chrome
# 以发布模式运行
flutter run --release
# 检查Flutter环境配置
flutter doctor
# 列出连接的设备
flutter devices
# 获取所有依赖包
flutter pub get
# 添加依赖包
flutter pub add package_name
# 添加特定版本的依赖
flutter pub add package_name@^1.0.0
# 添加开发依赖
flutter pub add --dev package_name
# 移除依赖包
flutter pub remove package_name
# 清理缓存(解决依赖问题)
flutter clean
# 显示帮助信息
flutter help
# 查看Flutter版本
flutter --version
# 列出所有可用的命令
flutter commands
# 构建APK(包含 arm64-v8a、armeabi-v7a、x86_64)
flutter build apk
# 构建拆分APK(按架构,会生成多个 APK 文件)
flutter build apk --split-per-abi
# 构建App Bundle
flutter build appbundle
# 构建iOS(需要Mac)
flutter build ios
# 构建Web
flutter build web
# 构建桌面应用
flutter build windows
flutter build macos
flutter build linux
项目结构
my_flutter_app/
├── android/ # Android 原生代码目录
├── ios/ # iOS 原生代码目录
├── lib/ # Flutter 核心代码目录(主要开发目录)
│ ├── main.dart # 应用程序入口文件
│ ├── models/ # 数据模型
│ ├── views/ # 视图/页面
│ ├── widgets/ # 可复用的组件
│ ├── services/ # 服务(API、数据库等)
│ ├── utils/ # 工具类/辅助函数
│ ├── providers/ # 状态管理(如使用 Provider)
│ └── routes/ # 路由配置
├── test/ # 测试代码目录
├── web/ # Web 平台代码
├── macos/ # macOS 桌面平台代码
├── windows/ # Windows 桌面平台代码
├── linux/ # Linux 桌面平台代码
├── assets/ # 静态资源文件
│ ├── images/ # 图片资源
│ ├── fonts/ # 字体文件
│ ├── icons/ # 图标文件
│ └── json/ # JSON 数据文件
├── build/ # 构建输出目录(自动生成,忽略)
├── .dart_tool/ # Dart 工具缓存(自动生成,忽略)
├── .idea/ # IDE 配置目录(自动生成,忽略)
├── .vscode/ # VS Code 配置
├── .metadata # Flutter 项目元数据
├── .packages # 依赖包映射(自动生成)
├── .flutter-plugins # Flutter 插件列表(自动生成)
├── pubspec.yaml # 项目配置文件(依赖、资源等)
├── pubspec.lock # 依赖版本锁定文件
├── README.md # 项目说明文档
├── CHANGELOG.md # 版本更新日志
├── LICENSE # 开源协议
└── analysis_options.yaml # 代码分析配置
2.脚手架Scoffold
Scaffold 是 Flutter 中实现 Material Design 布局结构的基础组件,它提供了标准的应用框架。
基本结构
Scaffold(
appBar: AppBar(), // 顶部导航栏
body: Container(), // 主体内容
floatingActionButton: FloatingActionButton(), // 悬浮按钮
bottomNavigationBar: BottomNavigationBar(), // 底部导航栏
drawer: Drawer(), // 左侧抽屉菜单
endDrawer: Drawer(), // 右侧抽屉菜单
backgroundColor: Colors.white, // 背景颜色
)
基础示例
import 'package:flutter/material.dart';
void main() {
runApp( MaterialApp(
title: "Scaffold学习项目",
home: Scaffold(
appBar: AppBar(
title: Text("Scaffold测试"),
),
body: Container(
child: Center(
child: Text("中间内容"),
),
),
bottomNavigationBar: Container(
height: 80,
child: Center(
child: Text("底部内容"),
),
),
floatingActionButton: FloatingActionButton(
onPressed: (){},
child: Icon(Icons.add),
),
// 左侧抽屉
drawer: Drawer(
child: Center(
child: Text("左侧侧边栏"),
),
),
// 右侧抽屉
endDrawer: Drawer(
child: Center(
child: Text("右侧侧边栏"),
),
),
backgroundColor: Colors.blueGrey,
),
));
}
3.无状态组件StatelessWidget
- 定义:创建一个新的类,继承StatelessWidget类并实现build方法
- 要求:build返回一个widget
- 场景:纯展示型组件,没有用户交互操作
案例
import 'package:flutter/material.dart';
void main(List<String> args) {
runApp(MainPage());
}
class MainPage extends StatelessWidget{
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "StatelessWidget无状态组件",
home: Scaffold(
appBar: AppBar(
title: Text("StatelessWidget无状态组件"),
),
body: Container(
child: Center(
child: Text("中间内容."),
),
),
bottomNavigationBar: Container(
height: 80,
child: Center(
child: Text("底部内容"),
),
),
),
);
}
}
生命周期
class MyStatelessWidget extends StatelessWidget {
// 1. 构造函数(创建时执行)
MyStatelessWidget({Key? key}) : super(key: key) {
print('1. 构造函数执行');
}
@override
Widget build(BuildContext context) {
// 2. build 方法执行(绘制UI)
print('2. build 方法执行');
return Container();
}
// ⚠️ StatelessWidget 只有这两个阶段!
// 没有更新、没有销毁,一次构建后就不再变化
}
4.有状态组件StatefulWidget
案例
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
// StatefulWidget 定义
class MyApp extends StatefulWidget {
@override
State<MyApp> createState() => _MyAppState();
}
// 状态类
class _MyAppState extends State<MyApp> {
int count = 0;
// 点击时调用的方法
void addNumber() {
setState(() {
count++; // 数字加1
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('有状态组件')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('你点击了 $count 次'), // 显示变化的数字
SizedBox(height: 20),
ElevatedButton(
onPressed: addNumber, // 点击按钮
child: Text('点我'),
),
],
),
),
),
);
}
}
生命周期
import 'package:flutter/material.dart';
void main() {
runApp(MainPage());
}
class MainPage extends StatefulWidget {
MainPage({Key? key}) : super(key: key) {
print('🔵 StatefulWidget 构造函数');
}
@override
State<MainPage> createState() {
print('🔵 createState 方法');
return _MainPageState();
}
}
class _MainPageState extends State<MainPage> {
// 1. 初始化状态变量
int _counter = 0;
// 2. 初始化生命周期
@override
void initState() {
super.initState();
print('🟢 1. initState 执行 - 组件初始化');
// 适合在这里做:网络请求、订阅、初始化数据
}
// 3. 依赖变化时(较少用)
@override
void didChangeDependencies() {
super.didChangeDependencies();
print('🟡 2. didChangeDependencies 执行 - 依赖变化');
// 当依赖的 InheritedWidget 变化时调用
}
// 4. 组件更新时
@override
void didUpdateWidget(MainPage oldWidget) {
super.didUpdateWidget(oldWidget);
print('🟠 3. didUpdateWidget 执行 - 组件更新');
// 当父组件重建导致当前组件更新时调用
}
// 5. 构建UI(可能多次执行)
@override
Widget build(BuildContext context) {
print('🟣 4. build 执行 - 绘制UI');
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('生命周期演示'),
actions: [
IconButton(
icon: Icon(Icons.refresh),
onPressed: () {
// 触发重建
setState(() {});
},
),
],
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('点击次数: $_counter'),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
setState(() {
_counter++;
print('🟣 setState 触发 - 界面更新');
});
},
child: Text('点我'),
),
SizedBox(height: 30),
Container(
padding: EdgeInsets.all(16),
color: Colors.grey[200],
child: Column(
children: [
Text('生命周期顺序:', style: TextStyle(fontWeight: FontWeight.bold)),
Text('1. 构造函数 → 2. createState'),
Text('3. initState → 4. didChangeDependencies'),
Text('5. build → (等待交互)'),
Text('6. setState → 重新build'),
Text('7. dispose → 组件销毁'),
],
),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// 导航到新页面演示 dispose
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondPage()),
);
},
child: Icon(Icons.arrow_forward),
),
),
);
}
// 6. 组件销毁时
@override
void dispose() {
print('🔴 5. dispose 执行 - 组件销毁');
// 适合在这里:取消订阅、释放资源
super.dispose();
}
}
// 第二个页面,演示 dispose
class SecondPage extends StatefulWidget {
@override
_SecondPageState createState() => _SecondPageState();
}
class _SecondPageState extends State<SecondPage> {
@override
void initState() {
super.initState();
print('🟢 第二页 initState');
}
@override
void dispose() {
print('🔴 第二页 dispose');
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('第二页'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('返回'),
),
),
);
}
}
生命周期流程图
StatefulWidget 创建
↓
【构造函数】 → 创建组件
↓
【createState】 → 创建状态对象
↓
【initState】 → 初始化(只执行一次)
↓
【didChangeDependencies】 → 依赖变化(可能执行多次)
↓
【build】 → 构建UI(可能执行多次)
↓
↙️ ↘️
交互触发 父组件重建
【setState】 【didUpdateWidget】
↘️ ↙️
【build】(重新构建)
↓
【dispose】 → 组件销毁(只执行一次)
5.手势
import 'package:flutter/material.dart';
void main() {
runApp( MaterialApp(
title: "Scaffold学习项目",
home: Scaffold(
appBar: AppBar(
title: Text("Scaffold测试"),
),
body: Container(
child: Center(
child: GestureDetector(
onTap: (){
print("点击");
},
onDoubleTap: (){
print("双击");
},
child: Text("中间内容"),
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: (){
print("悬浮按钮点击");
},
child: Icon(Icons.add),
),
),
));
}
6.状态更新
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
// StatefulWidget 定义
class MyApp extends StatefulWidget {
@override
State<MyApp> createState() => _MyAppState();
}
// 状态类
class _MyAppState extends State<MyApp> {
int count = 0;
// 点击时调用的方法
void addNumber() {
setState(() {
count++; // 数字加1
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('有状态组件')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('你点击了 $count 次'), // 显示变化的数字
SizedBox(height: 20),
ElevatedButton(
onPressed: addNumber, // 点击按钮
child: Text('点我'),
),
],
),
),
),
);
}
}
7. 基础组件
基础组件是Flutter中最常用的UI元素,用于展示内容和接收用户输入。
7.1 Text - 文本组件
组件介绍: Text是Flutter中最基础的文本显示组件,用于展示各种格式的文本内容。它支持设置字体大小、颜色、粗细、对齐方式等样式属性,还可以处理文本溢出、最多显示行数等情况。
核心属性:
data/child:要显示的文本内容style:文本样式(TextStyle对象)textAlign:对齐方式(left/right/center/justify)maxLines:最大显示行数overflow:文本溢出处理方式
简单示例:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Text组件示例')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// 基础文本
Text('Hello Flutter'),
SizedBox(height: 20),
// 带样式的文本
Text(
'样式丰富的文本',
style: TextStyle(
fontSize: 24,
color: Colors.blue,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 20),
// 带溢出处理的文本
Text(
'这是一段很长的文本,用来演示Text组件的溢出处理效果',
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
),
),
),
);
}
}
7.2 Button - 按钮组件
组件介绍: Flutter提供了多种按钮组件,用于响应用户的点击操作。不同类型的按钮有不同的视觉效果,适用于不同的场景。
按钮类型:
ElevatedButton:凸起按钮,有阴影效果,适用于主要操作TextButton:文本按钮,无背景,适用于次要操作OutlinedButton:边框按钮,有边框,适用于中等强调的操作IconButton:图标按钮,只显示图标FloatingActionButton:悬浮按钮,通常放在屏幕右下角
核心属性:
onPressed:点击回调函数(设为null时按钮禁用)child:按钮内容(文本或图标)style:按钮样式
简单示例:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('按钮组件示例')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// 凸起按钮
ElevatedButton(
onPressed: () => print('点击了ElevatedButton'),
child: Text('ElevatedButton'),
),
SizedBox(height: 20),
// 文本按钮
TextButton(
onPressed: () => print('点击了TextButton'),
child: Text('TextButton'),
),
SizedBox(height: 20),
// 边框按钮
OutlinedButton(
onPressed: () => print('点击了OutlinedButton'),
child: Text('OutlinedButton'),
),
SizedBox(height: 20),
// 图标按钮
IconButton(
onPressed: () => print('点击了IconButton'),
icon: Icon(Icons.favorite),
color: Colors.red,
),
],
),
),
// 悬浮按钮通常在Scaffold的floatingActionButton位置
floatingActionButton: FloatingActionButton(
onPressed: () => print('点击了FloatingActionButton'),
child: Icon(Icons.add),
),
),
);
}
}
7.3 Image - 图片组件
组件介绍: Image组件用于在应用中显示图片,支持从不同来源加载图片:网络、本地资源、文件、内存等。它提供了丰富的参数来控制图片的显示方式。
图片来源:
Image.network:从网络加载图片Image.asset:从项目资源加载图片Image.file:从本地文件加载图片Image.memory:从内存数据加载图片
核心属性:
fit:图片填充模式(cover/contain/fill等)width/height:图片宽高loadingBuilder:加载中的占位图errorBuilder:加载失败时的显示内容
简单示例:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('图片组件示例')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// 网络图片
Image.network(
'https://picsum.photos/200/150',
width: 200,
height: 150,
fit: BoxFit.cover,
),
SizedBox(height: 20),
// 带加载状态的网络图片
Image.network(
'https://picsum.photos/200/150?image=2',
width: 200,
height: 150,
fit: BoxFit.cover,
loadingBuilder: (context, child, progress) {
if (progress == null) return child;
return Center(
child: CircularProgressIndicator(
value: progress.cumulativeBytesLoaded /
(progress.expectedTotalBytes ?? 1),
),
);
},
),
],
),
),
),
);
}
}
7.4 Icon - 图标组件
组件介绍: Icon组件用于显示Material Design图标,Flutter内置了大量常用的图标。图标可以设置颜色、大小,也可以自定义图标。
核心属性:
icon:要显示的图标(Icons.xxx)size:图标大小color:图标颜色
简单示例:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('图标组件示例')),
body: Center(
child: Wrap(
spacing: 30,
children: [
Icon(Icons.home, size: 40, color: Colors.blue),
Icon(Icons.favorite, size: 40, color: Colors.red),
Icon(Icons.settings, size: 40, color: Colors.grey),
Icon(Icons.notifications, size: 40, color: Colors.amber),
Icon(Icons.person, size: 40, color: Colors.green),
],
),
),
),
);
}
}
7.5 TextField - 文本输入框
组件介绍: TextField是Flutter中的文本输入组件,用于接收用户输入的文字。它支持密码输入、多行输入、输入格式验证等功能。
核心属性:
controller:控制文本的控制器decoration:输入框装饰(边框、标签、提示文字等)obscureText:是否隐藏输入(用于密码)keyboardType:键盘类型(数字、邮箱、电话等)onChanged:内容变化时的回调onSubmitted:提交时的回调
简单示例:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final TextEditingController _controller = TextEditingController();
String _displayText = '';
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('TextField示例')),
body: Padding(
padding: EdgeInsets.all(20),
child: Column(
children: [
// 基础输入框
TextField(
decoration: InputDecoration(
labelText: '用户名',
hintText: '请输入用户名',
border: OutlineInputBorder(),
prefixIcon: Icon(Icons.person),
),
),
SizedBox(height: 20),
// 密码输入框
TextField(
obscureText: true,
decoration: InputDecoration(
labelText: '密码',
hintText: '请输入密码',
border: OutlineInputBorder(),
prefixIcon: Icon(Icons.lock),
),
),
SizedBox(height: 20),
// 带回调的输入框
TextField(
controller: _controller,
decoration: InputDecoration(
labelText: '输入内容',
border: OutlineInputBorder(),
),
onChanged: (value) {
setState(() {
_displayText = value;
});
},
),
SizedBox(height: 20),
Text('你输入的是:$_displayText'),
],
),
),
),
);
}
}
8. 布局组件
布局组件用于组织和排列其他组件,决定它们在屏幕上的位置和大小。
8.1 Container - 容器组件
组件介绍: Container是Flutter中最常用的布局组件,相当于一个"盒子",可以容纳一个子组件,并对其进行装饰、定位、大小调整等操作。
核心属性:
width/height:容器宽高padding/margin:内边距/外边距decoration:装饰(背景颜色、边框、圆角、阴影等)alignment:子组件对齐方式color:背景颜色(简单场景使用)
简单示例:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Container示例')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// 简单容器
Container(
width: 200,
height: 100,
color: Colors.blue,
child: Center(
child: Text('简单容器', style: TextStyle(color: Colors.white)),
),
),
SizedBox(height: 20),
// 带边框和圆角的容器
Container(
width: 200,
height: 100,
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.red, width: 2),
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 5,
offset: Offset(2, 2),
),
],
),
child: Center(child: Text('带边框和圆角')),
),
],
),
),
),
);
}
}
8.2 Row - 水平布局组件
组件介绍: Row是一个水平排列子组件的布局组件,子组件会从左到右依次排列。它类似于HTML中的flex布局。
核心属性:
mainAxisAlignment:主轴(水平方向)的对齐方式crossAxisAlignment:交叉轴(垂直方向)的对齐方式children:子组件列表
简单示例:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Row示例')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('默认左对齐:'),
Container(
color: Colors.grey[200],
child: Row(
children: [
Container(width: 50, height: 50, color: Colors.red),
Container(width: 50, height: 50, color: Colors.green),
Container(width: 50, height: 50, color: Colors.blue),
],
),
),
SizedBox(height: 20),
Text('居中对齐:'),
Container(
color: Colors.grey[200],
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(width: 50, height: 50, color: Colors.red),
Container(width: 50, height: 50, color: Colors.green),
Container(width: 50, height: 50, color: Colors.blue),
],
),
),
SizedBox(height: 20),
Text('两端对齐:'),
Container(
color: Colors.grey[200],
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(width: 50, height: 50, color: Colors.red),
Container(width: 50, height: 50, color: Colors.green),
Container(width: 50, height: 50, color: Colors.blue),
],
),
),
],
),
),
),
);
}
}
8.3 Column - 垂直布局组件
组件介绍: Column是一个垂直排列子组件的布局组件,子组件会从上到下依次排列。它是Row的垂直版本。
核心属性:
mainAxisAlignment:主轴(垂直方向)的对齐方式crossAxisAlignment:交叉轴(水平方向)的对齐方式children:子组件列表
简单示例:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Column示例')),
body: Center(
child: Container(
height: 300,
color: Colors.grey[200],
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(width: 100, height: 50, color: Colors.red),
Container(width: 100, height: 50, color: Colors.green),
Container(width: 100, height: 50, color: Colors.blue),
],
),
),
),
),
);
}
}
8.4 Expanded - 弹性布局组件
组件介绍: Expanded用于在Row、Column或Flex中展开子组件,让它填充剩余空间。可以设置flex参数来控制多个Expanded之间的比例。
核心属性:
flex:弹性因子,决定占据剩余空间的比例child:要展开的子组件
简单示例:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Expanded示例')),
body: Center(
child: Column(
children: [
Text('1:2:1 比例布局:'),
Container(
height: 100,
color: Colors.grey[200],
child: Row(
children: [
Expanded(
flex: 1,
child: Container(color: Colors.red, child: Center(child: Text('1'))),
),
Expanded(
flex: 2,
child: Container(color: Colors.green, child: Center(child: Text('2'))),
),
Expanded(
flex: 1,
child: Container(color: Colors.blue, child: Center(child: Text('1'))),
),
],
),
),
SizedBox(height: 20),
Text('搜索框 + 按钮布局:'),
Container(
padding: EdgeInsets.all(10),
color: Colors.grey[200],
child: Row(
children: [
Expanded(
child: TextField(
decoration: InputDecoration(
hintText: '搜索...',
border: OutlineInputBorder(),
),
),
),
SizedBox(width: 10),
ElevatedButton(
onPressed: () {},
child: Text('搜索'),
),
],
),
),
],
),
),
),
);
}
}
8.5 Stack - 层叠布局组件
组件介绍: Stack允许子组件叠加在一起,后添加的子组件会覆盖在先添加的子组件上面。结合Positioned可以精确控制子组件的位置。
核心属性:
alignment:未使用Positioned的子组件的对齐方式children:要叠加的子组件列表
简单示例:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Stack示例')),
body: Center(
child: Container(
width: 300,
height: 300,
color: Colors.grey[200],
child: Stack(
children: [
// 底层的红色方块
Container(
width: 200,
height: 200,
color: Colors.red,
),
// 中间的绿色方块(偏移位置)
Positioned(
top: 50,
left: 50,
child: Container(
width: 200,
height: 200,
color: Colors.green.withOpacity(0.7),
),
),
// 顶层的蓝色文字
Positioned(
bottom: 50,
right: 50,
child: Container(
padding: EdgeInsets.all(10),
color: Colors.blue,
child: Text(
'顶层文字',
style: TextStyle(color: Colors.white),
),
),
),
],
),
),
),
),
);
}
}
8.6 Center - 居中布局组件
组件介绍: Center是一个简单的布局组件,它会将子组件放在父容器的中心位置。相当于alignment: Alignment.center的Container。
核心属性:
child:要居中的子组件
简单示例:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Center示例')),
body: Center(
child: Container(
width: 200,
height: 200,
color: Colors.blue,
child: Center(
child: Text(
'居中内容',
style: TextStyle(color: Colors.white, fontSize: 20),
),
),
),
),
),
);
}
}
8.7 Padding - 内边距组件
组件介绍: Padding用于给子组件添加内边距,即子组件与父容器边界之间的空白区域。
核心属性:
padding:内边距大小(EdgeInsets对象)child:子组件
简单示例:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Padding示例')),
body: Column(
children: [
// 没有内边距
Container(
color: Colors.grey[200],
child: Container(
color: Colors.blue,
child: Text('没有内边距'),
),
),
SizedBox(height: 20),
// 有内边距
Container(
color: Colors.grey[200],
child: Padding(
padding: EdgeInsets.all(20),
child: Container(
color: Colors.blue,
child: Text('有20的内边距'),
),
),
),
SizedBox(height: 20),
// 不同方向的内边距
Container(
color: Colors.grey[200],
child: Padding(
padding: EdgeInsets.only(left: 30, top: 10, right: 10, bottom: 30),
child: Container(
color: Colors.green,
child: Text('左边距30,上边距10,右边距10,下边距30'),
),
),
),
],
),
),
);
}
}
8.8 Wrap - 流式布局组件
组件介绍: Wrap类似于Row和Column,但当空间不足时会自动换行/换列。非常适合用于标签列表、按钮组等需要自动换行的场景。
核心属性:
direction:主轴方向(水平或垂直)spacing:主轴方向间距runSpacing:交叉轴方向间距alignment:主轴对齐方式
简单示例:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
final List<String> tags = ['Flutter', 'Dart', 'Android', 'iOS', 'Web', '前端', '后端'];
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Wrap示例')),
body: Padding(
padding: EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('标签列表(自动换行):'),
SizedBox(height: 10),
Container(
padding: EdgeInsets.all(10),
color: Colors.grey[200],
child: Wrap(
spacing: 10,
runSpacing: 10,
children: tags.map((tag) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6),
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(20),
),
child: Text(
tag,
style: TextStyle(color: Colors.white),
),
);
}).toList(),
),
),
],
),
),
),
);
}
}
9. 滚动组件
滚动组件用于处理内容超出屏幕范围的情况,让用户可以滑动查看所有内容。
9.1 SingleChildScrollView - 单子滚动组件
组件介绍: 当单个子组件的内容可能超出屏幕范围时,用SingleChildScrollView包裹即可实现滚动。常用于表单、长文章等场景。
核心属性:
scrollDirection:滚动方向(默认垂直)physics:滚动物理效果(弹性/阻尼等)padding:内边距
简单示例:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('SingleChildScrollView示例')),
body: SingleChildScrollView(
padding: EdgeInsets.all(20),
child: Column(
children: List.generate(20, (index) {
return Container(
margin: EdgeInsets.only(bottom: 10),
height: 100,
color: Colors.primaries[index % Colors.primaries.length],
child: Center(
child: Text(
'Item ${index + 1}',
style: TextStyle(color: Colors.white, fontSize: 20),
),
),
);
}),
),
),
),
);
}
}
9.2 ListView - 列表组件
组件介绍: ListView是最常用的滚动列表组件,用于展示大量数据的列表。它支持垂直和水平滚动,有懒加载特性,性能较好。
常用构造方法:
ListView:直接创建,适合少量数据ListView.builder:动态构建,适合大量数据(懒加载)ListView.separated:带分割线的动态列表
核心属性:
itemCount:列表项数量itemBuilder:构建列表项的函数separatorBuilder:构建分割线的函数
简单示例:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('ListView示例')),
body: ListView.builder(
itemCount: 50,
itemBuilder: (context, index) {
return ListTile(
leading: CircleAvatar(
backgroundColor: Colors.primaries[index % Colors.primaries.length],
child: Text('${index + 1}'),
),
title: Text('标题 ${index + 1}'),
subtitle: Text('这是第 ${index + 1} 项的描述文字'),
trailing: Icon(Icons.arrow_forward_ios),
onTap: () {
print('点击了第 ${index + 1} 项');
},
);
},
),
),
);
}
}
9.3 GridView - 网格组件
组件介绍: GridView用于展示网格布局的数据,类似于九宫格。常用于图片墙、商品展示等场景。
常用构造方法:
GridView.count:指定每行列数的网格GridView.builder:动态构建网格(懒加载)
核心属性:
crossAxisCount:每行的列数childAspectRatio:子元素宽高比crossAxisSpacing:列间距mainAxisSpacing:行间距
简单示例:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('GridView示例')),
body: GridView.count(
crossAxisCount: 2, // 每行2列
childAspectRatio: 1.2, // 宽高比
crossAxisSpacing: 10, // 列间距
mainAxisSpacing: 10, // 行间距
padding: EdgeInsets.all(10),
children: List.generate(20, (index) {
return Container(
color: Colors.primaries[index % Colors.primaries.length],
child: Center(
child: Text(
'Item ${index + 1}',
style: TextStyle(color: Colors.white, fontSize: 18),
),
),
);
}),
),
),
);
}
}
9.4 PageView - 页面滑动组件
组件介绍: PageView用于实现左右滑动的页面切换效果,常用于引导页、轮播图、标签页等场景。
核心属性:
children:页面列表onPageChanged:页面切换回调controller:页面控制器
简单示例:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('PageView示例')),
body: PageView(
children: [
Container(color: Colors.red, child: Center(child: Text('第1页', style: TextStyle(color: Colors.white, fontSize: 30)))),
Container(color: Colors.green, child: Center(child: Text('第2页', style: TextStyle(color: Colors.white, fontSize: 30)))),
Container(color: Colors.blue, child: Center(child: Text('第3页', style: TextStyle(color: Colors.white, fontSize: 30)))),
],
),
),
);
}
}
10.页面框架组件
页面框架组件用于构建应用的整体页面结构,提供标准的布局骨架。
10.1 Scaffold - 页面脚手架
组件介绍: Scaffold 是 Material Design 页面的核心骨架,它实现了标准的应用布局结构。几乎每个页面都需要用它来组织 AppBar、底部导航、悬浮按钮等元素。
核心属性:
appBar:顶部导航栏body:页面主体内容bottomNavigationBar:底部导航栏floatingActionButton:悬浮按钮drawer:左侧抽屉菜单endDrawer:右侧抽屉菜单backgroundColor:背景颜色
简单示例:
Scaffold(
appBar: AppBar(title: Text('首页')),
body: Center(child: Text('页面内容')),
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页'),
BottomNavigationBarItem(icon: Icon(Icons.person), label: '我的'),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add),
),
drawer: Drawer(child: Center(child: Text('侧边菜单'))),
)
10.2 AppBar - 顶部导航栏
组件介绍: AppBar 位于页面顶部,通常包含标题、返回按钮、操作按钮等。它可以固定在顶部,也可以随着滚动隐藏。
核心属性:
title:标题leading:左侧图标(默认是返回按钮)actions:右侧操作按钮列表backgroundColor:背景颜色elevation:阴影高度bottom:底部区域(常用 TabBar)
简单示例:
AppBar(
title: Text('聊天详情'),
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () => Navigator.pop(context),
),
actions: [
IconButton(icon: Icon(Icons.search), onPressed: () {}),
IconButton(icon: Icon(Icons.more_vert), onPressed: () {}),
],
backgroundColor: Colors.blue,
elevation: 4,
)
带 TabBar 的 AppBar:
AppBar(
title: Text('分类'),
bottom: TabBar(
tabs: [
Tab(text: '热门'),
Tab(text: '推荐'),
Tab(text: '最新'),
],
),
)
10.3 BottomNavigationBar - 底部导航栏
组件介绍: BottomNavigationBar 位于页面底部,用于在应用的主要页面之间切换。通常配合 IndexedStack 或 PageView 实现页面切换。
核心属性:
items:导航项列表currentIndex:当前选中项索引onTap:点击回调type:导航类型(fixed/shifting)selectedItemColor:选中项颜色
简单示例:
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int _currentIndex = 0;
final pages = [
Center(child: Text('首页')),
Center(child: Text('发现')),
Center(child: Text('消息')),
Center(child: Text('我的')),
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: pages[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
onTap: (index) {
setState(() {
_currentIndex = index;
});
},
type: BottomNavigationBarType.fixed, // 超过3个用fixed
selectedItemColor: Colors.blue,
unselectedItemColor: Colors.grey,
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页'),
BottomNavigationBarItem(icon: Icon(Icons.explore), label: '发现'),
BottomNavigationBarItem(icon: Icon(Icons.message), label: '消息'),
BottomNavigationBarItem(icon: Icon(Icons.person), label: '我的'),
],
),
);
}
}
10.4 Drawer - 侧边抽屉菜单
组件介绍: Drawer 是从屏幕边缘滑出的侧边菜单,通常放置用户信息、导航选项、设置等。左侧常用,右侧也有(endDrawer)。
核心属性:
child:菜单内容width:抽屉宽度(默认 304)elevation:阴影高度
简单示例:
Scaffold(
appBar: AppBar(title: Text('首页')),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
// 头部
DrawerHeader(
decoration: BoxDecoration(color: Colors.blue),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CircleAvatar(
radius: 30,
backgroundImage: NetworkImage('头像URL'),
),
SizedBox(height: 10),
Text('用户名', style: TextStyle(color: Colors.white)),
Text('user@example.com', style: TextStyle(color: Colors.white70)),
],
),
),
// 菜单项
ListTile(
leading: Icon(Icons.home),
title: Text('首页'),
onTap: () => Navigator.pop(context),
),
ListTile(
leading: Icon(Icons.settings),
title: Text('设置'),
onTap: () => Navigator.pop(context),
),
Divider(),
ListTile(
leading: Icon(Icons.logout),
title: Text('退出登录'),
onTap: () {},
),
],
),
),
)
10.5 FloatingActionButton - 悬浮按钮
组件介绍: FloatingActionButton 是悬浮在页面上的圆形按钮,通常用于主要操作(如添加、编辑)。可以放在 Scaffold 的 floatingActionButton 位置,也可以自定义位置。
核心属性:
onPressed:点击回调child:图标或文字backgroundColor:背景颜色mini:是否迷你尺寸shape:形状(默认圆形)
简单示例:
Scaffold(
appBar: AppBar(title: Text('笔记')),
body: ListView(...),
floatingActionButton: FloatingActionButton(
onPressed: () {
// 跳转到添加笔记页面
},
child: Icon(Icons.add),
backgroundColor: Colors.red,
),
)
扩展按钮(带文字):
FloatingActionButton.extended(
onPressed: () {},
icon: Icon(Icons.add),
label: Text('添加笔记'),
backgroundColor: Colors.green,
)
多个悬浮按钮:
Scaffold(
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
heroTag: 'btn1',
onPressed: () {},
child: Icon(Icons.camera),
mini: true,
),
SizedBox(height: 10),
FloatingActionButton(
heroTag: 'btn2',
onPressed: () {},
child: Icon(Icons.photo),
mini: true,
),
SizedBox(height: 10),
FloatingActionButton(
heroTag: 'btn3',
onPressed: () {},
child: Icon(Icons.add),
),
],
),
)
10.6 TabBar + TabBarView - 标签页
组件介绍: TabBar 和 TabBarView 配合使用,实现顶部标签页切换效果。TabBar 显示标签,TabBarView 显示对应的页面内容。
核心属性:
TabBar:标签栏(需要配合 TabController)TabBarView:标签页内容DefaultTabController:简化使用的控制器
简单示例:
class TabDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: Text('标签页示例'),
bottom: TabBar(
tabs: [
Tab(icon: Icon(Icons.directions_car)),
Tab(icon: Icon(Icons.directions_transit)),
Tab(icon: Icon(Icons.directions_bike)),
],
),
),
body: TabBarView(
children: [
Center(child: Text('汽车内容')),
Center(child: Text('公交内容')),
Center(child: Text('自行车内容')),
],
),
),
);
}
}
带文字的 TabBar:
TabBar(
tabs: [
Tab(text: '热门'),
Tab(text: '推荐'),
Tab(text: '最新'),
],
indicatorColor: Colors.red, // 指示器颜色
labelColor: Colors.blue, // 选中标签颜色
unselectedLabelColor: Colors.grey, // 未选中标签颜色
)
10.7 BottomSheet - 底部弹出面板
组件介绍: BottomSheet 是从屏幕底部弹出的面板,用于显示更多操作或内容。分为持久性(Persistent)和模态(Modal)两种。
核心属性:
builder:构建面板内容backgroundColor:背景颜色shape:形状(可设置圆角)
简单示例:
// 显示模态底部面板
ElevatedButton(
onPressed: () {
showModalBottomSheet(
context: context,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
),
builder: (context) => Container(
height: 200,
padding: EdgeInsets.all(20),
child: Column(
children: [
Text('选择操作', style: TextStyle(fontSize: 18)),
ListTile(
leading: Icon(Icons.photo),
title: Text('相册'),
onTap: () => Navigator.pop(context),
),
ListTile(
leading: Icon(Icons.camera),
title: Text('相机'),
onTap: () => Navigator.pop(context),
),
],
),
),
);
},
child: Text('显示底部面板'),
)
10.8 SnackBar - 底部提示条
组件介绍: SnackBar 是在屏幕底部短暂显示的轻量级提示信息,可以包含操作按钮。
核心属性:
content:显示内容action:操作按钮duration:显示时长behavior:显示行为(浮动/固定)
简单示例:
ElevatedButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('操作成功'),
action: SnackBarAction(
label: '撤销',
onPressed: () {
// 撤销操作
},
),
duration: Duration(seconds: 2),
behavior: SnackBarBehavior.floating, // 浮动显示
),
);
},
child: Text('显示提示'),
)