4.1 Flutter 项目的基本结构
当你创建一个新的 Flutter 项目时,会自动生成以下文件结构:
my_app/ # 项目根目录
├── android/ # Android 原生代码
├── ios/ # iOS 原生代码
├── linux/ # Linux 原生代码
├── macos/ # macOS 原生代码
├── web/ # Web 相关文件
├── windows/ # Windows 原生代码
├── lib/ # 🌟 Dart 代码(我们主要工作的地方)
│ └── main.dart # 应用入口文件
├── test/ # 测试代码
├── .gitignore # Git 忽略文件配置
├── analysis_options.yaml # Dart 代码分析配置
├── pubspec.yaml # 🌟 项目配置文件(依赖管理)
└── README.md # 项目说明文档我们主要关注的目录
作为 Flutter 开发者,我们主要工作在以下两个文件/目录:
pubspec.yaml- 配置项目信息和依赖lib/- 编写 Dart 代码
4.2 pubspec.yaml 详解
pubspec.yaml 是 Flutter 项目的配置文件,相当于 Node.js 的 package.json 或 Python 的 requirements.txt。
基础配置
1# 应用名称(只能用小写字母和下划线)
2name: todo_app
3
4# 应用描述
5description: A complete Flutter Todo application with Provider state management
6
7# 发布配置('none' 表示不发布到 pub.dev)
8publish_to: 'none'
9
10# 版本号:主版本.次版本.修订+构建号
11version: 1.0.0+1环境配置
1# 指定 Dart SDK 版本范围
2environment:
3 sdk: '>=3.0.0 <4.0.0'这表示项目需要 Dart 3.0.0 或更高版本,但低于 4.0.0。
依赖配置
1dependencies:
2 # Flutter SDK 本身
3 flutter:
4 sdk: flutter
5
6 # 状态管理
7 provider: ^6.1.1
8
9 # 本地存储
10 shared_preferences: ^2.2.2
11
12 # UUID 生成
13 uuid: ^4.3.3
14
15 # Material Design 图标
16 material_design_icons_flutter: ^7.0.7296版本号说明:
| 写法 | 含义 | 示例 |
|---|---|---|
^1.2.3 |
兼容 1.2.3 及以上,但小于 2.0.0 | ^6.1.1 → 6.1.1 到 6.x.x |
>=1.2.0 |
大于等于 1.2.0 | 任何更新的版本 |
<2.0.0 |
小于 2.0.0 | 1.x.x 版本 |
1.2.3 |
固定版本 | 只能是 1.2.3 |
开发依赖
1dev_dependencies:
2 # 测试框架
3 flutter_test:
4 sdk: flutter
5
6 # 代码规范检查
7 flutter_lints: ^3.0.1开发依赖只在开发时使用,不会打包到最终应用中。
Flutter 特定配置
1flutter:
2 # 使用 Material Design 图标字体
3 uses-material-design: true
4
5 # 资源文件(图片、字体等)
6 assets:
7 - assets/images/
8 - assets/icons/
9
10 # 自定义字体
11 fonts:
12 - family: CustomFont
13 fonts:
14 - asset: assets/fonts/custom_font.ttf安装依赖
修改 pubspec.yaml 后,运行以下命令安装依赖:
1flutter pub get4.3 待办事项应用的项目结构
我们的待办事项应用采用了清晰的分层结构:
todo_app/
├── lib/ # Dart 源代码
│ ├── main.dart # 应用入口,主题配置
│ ├── models/ # 数据模型层
│ │ └── task.dart # 任务数据模型
│ ├── providers/ # 状态管理层
│ │ └── task_provider.dart # 任务状态管理
│ ├── services/ # 服务层
│ │ └── storage_service.dart # 本地存储服务
│ ├── screens/ # 页面层
│ │ └── home_screen.dart # 主页面
│ └── widgets/ # 组件层
│ ├── task_item.dart # 任务列表项
│ ├── add_task_dialog.dart # 添加任务对话框
│ ├── filter_chip_bar.dart # 筛选栏
│ └── empty_state.dart # 空状态视图
├── pubspec.yaml # 项目配置
└── ...分层架构说明
┌─────────────────────────────────────┐
│ UI 层 (Widgets) │ ← 用户界面
│ task_item, add_task_dialog... │
├─────────────────────────────────────┤
│ 页面层 (Screens) │ ← 页面组织
│ home_screen.dart │
├─────────────────────────────────────┤
│ 状态层 (Providers) │ ← 业务逻辑
│ task_provider.dart │
├─────────────────────────────────────┤
│ 服务层 (Services) │ ← 数据持久化
│ storage_service.dart │
├─────────────────────────────────────┤
│ 模型层 (Models) │ ← 数据结构
│ task.dart │
└─────────────────────────────────────┘各层职责
1. Models(模型层)
职责: 定义数据结构
示例: task.dart 定义了任务的数据结构
class Task {
final String id;
final String title;
final bool isCompleted;
final DateTime createdAt;
final DateTime? dueDate;
// ...
}2. Services(服务层)
职责: 处理数据持久化、网络请求等
示例: storage_service.dart 负责将任务保存到本地存储
class StorageService {
static Future saveTasks(List tasks) async {
// 保存到 SharedPreferences
}
static Future> loadTasks() async {
// 从 SharedPreferences 读取
}
}3. Providers(状态层)
职责: 管理应用状态,处理业务逻辑
示例: task_provider.dart 管理任务列表的状态
class TaskProvider extends ChangeNotifier {
List _tasks = [];
void addTask(String title) {
// 添加任务逻辑
notifyListeners(); // 通知 UI 更新
}
}4. Screens(页面层)
职责: 组织页面结构,连接 UI 和状态
示例: home_screen.dart 是应用的主页面
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(...),
body: TaskList(),
floatingActionButton: AddButton(),
);
}
}5. Widgets(组件层)
职责: 封装可复用的 UI 组件
示例: task_item.dart 封装了单个任务的显示样式
class TaskItem extends StatelessWidget {
final Task task;
@override
Widget build(BuildContext context) {
return ListTile(...);
}
}4.4 导入路径规则
在 Dart 中,导入文件有几种方式:
1. 导入 Dart/Flutter 内置库
import 'dart:convert'; // Dart 核心库
import 'package:flutter/material.dart'; // Flutter 库2. 导入第三方包
import 'package:provider/provider.dart';
import 'package:uuid/uuid.dart';3. 导入项目内文件
// 相对路径导入
import '../models/task.dart';
import '../providers/task_provider.dart';
import '../widgets/task_item.dart';导入路径对照表
| 当前文件 | 导入目标 | 写法 |
|---|---|---|
lib/screens/home_screen.dart |
lib/models/task.dart |
import '../models/task.dart'; |
lib/widgets/task_item.dart |
lib/models/task.dart |
import '../models/task.dart'; |
lib/main.dart |
lib/screens/home_screen.dart |
import 'screens/home_screen.dart'; |
lib/providers/task_provider.dart |
lib/services/storage_service.dart |
import '../services/storage_service.dart'; |
4.5 命名规范
Flutter/Dart 社区有一些约定俗成的命名规范:
文件命名
- 使用小写字母和下划线
- 单词之间用下划线分隔
✅ 好的命名:
- task_item.dart
- add_task_dialog.dart
- storage_service.dart
❌ 不好的命名:
- TaskItem.dart # 不要用大写
- addTaskDialog.dart # 不要用驼峰
- task-item.dart # 不要用连字符类命名
- 使用大驼峰命名法(PascalCase)
- 每个单词首字母大写
✅ 好的命名:
class TaskProvider { }
class StorageService { }
class AddTaskDialog { }
❌ 不好的命名:
class taskProvider { } # 首字母要小写
class storage_service { } # 不要用下划线
class addTaskDialog { } # 首字母要小写变量和函数命名
- 使用小驼峰命名法(camelCase)
- 首字母小写,后续单词首字母大写
✅ 好的命名:
String taskTitle;
void addTask() { }
bool isCompleted;
❌ 不好的命名:
String TaskTitle; # 首字母要小写
void add_task() { } # 不要用下划线
bool is_completed; # 不要用下划线常量命名
- 使用全大写和下划线
✅ 好的命名:
const String TASKS_KEY = 'tasks';
const int MAX_TASK_COUNT = 100;
❌ 不好的命名:
const String tasksKey = 'tasks'; # 常量要用全大写4.6 小结
| 目录/文件 | 作用 |
|---|---|
pubspec.yaml |
项目配置和依赖管理 |
lib/main.dart |
应用入口 |
lib/models/ |
数据模型定义 |
lib/providers/ |
状态管理 |
lib/services/ |
数据持久化服务 |
lib/screens/ |
页面组件 |
lib/widgets/ |
可复用 UI 组件 |
这种分层结构的好处:
- 职责清晰 - 每层只做一件事
- 易于维护 - 修改一处不影响其他地方
- 便于测试 - 可以单独测试每层
- 代码复用 - 组件可以在多个页面使用
下一步:第五章:数据模型详解