E-Brufen 技术选型全景:Flutter + 鸿蒙 + Hive CE
一、应用画像
| 维度 | E-Brufen |
|---|---|
| 类型 | 心理健康 / 情绪管理 |
| 平台 | HarmonyOS (6.1.0 / API 23) |
| 框架 | Flutter 3.6.2+ |
| 语言 | Dart 100%(零 Kotlin / Swift / ArkTS 业务代码) |
| 网络 | 完全离线,零网络权限 |
| 存储 | Hive CE(纯 Dart 键值存储) |
| 状态管理 | ChangeNotifier(零第三方状态库) |
| UI 范式 | Material 3 |
| 代码规模 | 约 2000 行 Dart(13 个源文件) |
| 页面数 | 4 个主页面 + 首页 |
| 依赖数量 | 仅 hive_ce + hive_ce_flutter 两个核心依赖 |
二、完整技术架构图
┌──────────────────────────────────────────────────────────────────┐
│ UI Layer (Pages) │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ HomePage │ │ DiaryPage │ │ BreathePage │ │
│ │ 首页 │ │ 情绪日记 │ │ 呼吸练习 │ │
│ │ │ │ · 记录 Tab │ │ · 模式选择 │ │
│ │ · 问候语 │ │ · 时间线 Tab │ │ · 呼吸动画 │ │
│ │ · 3 功能卡 │ │ · 统计 Tab │ │ · 暂停/继续 │ │
│ │ · 今日速记 │ │ │ │ │ │
│ └──────┬───────┘ └──────┬───────┘ └──────────┬───────────┘ │
│ │ │ │ │
│ ┌──────┴─────────────────┴──────────────────────┴───────────┐ │
│ │ SoundscapePage (白噪音 · 放松) │ │
│ │ 场景选择 → 定时器 → 视觉脉冲动画(无音频、纯视觉) │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ ↓ 监听 (addListener) / 数据流向 │
│ │
├──────────────────────────────────────────────────────────────────┤
│ Widget Layer (可复用组件) │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ HomeCard │ │ MoodPicker │ │ MoodChart │ │
│ │ 渐变功能卡片 │ │ 5 表情选择器 │ │ 周情绪柱状图(自绘) │ │
│ │ · emoji │ │ · 缩放动画 │ │ · 按日聚合均值 │ │
│ │ · 渐变背景 │ │ · 高亮状态 │ │ · 颜色映射 │ │
│ │ · 点击跳转 │ │ │ │ · 总结文案 │ │
│ └──────────────┘ └──────────────┘ └──────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ BreathingCircle (呼吸动画球) │ │
│ │ 模式支持: 4-7-8 呼吸法 / 盒式呼吸 / 放松呼吸 │ │
│ │ 动画: AnimationController + Timer 驱动缩放 + 透明度 │ │
│ │ 状态: pause() / resume() / 阶段标签回调 │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ↓ 读写数据 / 触发 notifyListeners() │
│ │
├──────────────────────────────────────────────────────────────────┤
│ State / Data Layer │
│ │
│ ┌─────────────────────────────────┐ ┌─────────────────────┐ │
│ │ MoodStorage │ │ AppSettings │ │
│ │ extends ChangeNotifier │ │ (plain Dart class) │ │
│ │ │ │ │ │
│ │ · insert() → notifyListeners │ │ · selectedScene │ │
│ │ · update() → notifyListeners │ │ · timerDuration │ │
│ │ · delete() → notifyListeners │ │ · breatheMode │ │
│ │ · getAll() / getByDate() │ │ · breatheMinutes │ │
│ │ · getByWeek() │ │ │ │
│ │ · getWeeklyMoodCounts() │ │ isReady 状态检查 │ │
│ └───────────────┬─────────────────┘ └──────────┬──────────┘ │
│ │ │ │
│ ↓ 读写 ↓ 读写 │
│ │
├──────────────────────────────────────────────────────────────────┤
│ Storage Layer │
│ │
│ ┌──────────────────────────┐ ┌──────────────────────────┐ │
│ │ Hive CE Box: 'moods' │ │ Hive CE Box: 'settings' │ │
│ │ │ │ │ │
│ │ Key: int (自增 ID) │ │ Key: String │ │
│ │ Value: JSON String │ │ Value: 原始类型 │ │
│ │ 编码: jsonEncode/Decode │ │ · String (场景/模式) │ │
│ │ 内容: MoodEntry 序列化 │ │ · int (定时/时长) │ │
│ │ │ │ │ │
│ │ 操作: CRUD + 时间查询 │ │ 操作: get/set + 默认值 │ │
│ └────────────┬─────────────┘ └────────────┬─────────────┘ │
│ │ │ │
│ ↓ 持久化(文件系统) ↓ │
│ │
├──────────────────────────────────────────────────────────────────┤
│ HarmonyOS Platform │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ EntryAbility.ets → Flutter Engine → Dart VM │ │
│ │ hvigor 构建 → HAP 签名 → 真机部署 │ │
│ │ │ │
│ │ 构建配置: ohos/build-profile.json5 │ │
│ │ 应用元信息: ohos/AppScope/app.json5 │ │
│ │ 图标资源: ohos/AppScope/resources/base/media/ │ │
│ │ 签名: .p12 + .p7b + .cer 证书链 │ │
│ └──────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
数据流示意:
用户操作 → Page(setState) → Widget rebuild
↓
用户保存数据 → MoodStorage.insert/update/delete
↓
MoodStorage.notifyListeners()
↓
Page.addListener 回调 → setState → Widget 刷新
↓
Hive.put() → 文件系统持久化
三、六大技术决策
决策 1:为什么是 Flutter?
背景:HarmonyOS 原生开发使用 ArkTS + ArkUI,而 Flutter 通过其鸿蒙引擎提供了一条跨平台路径。
决策理由:
| 维度 | Flutter | ArkTS 原生 |
|---|---|---|
| 跨平台潜力 | Android / iOS / Web / 鸿蒙,一套代码 | 仅鸿蒙 |
| 组件生态 | Material 3 开箱即用 | 需从零搭建 |
| 热重载 | 支持(秒级) | 不支持 |
| 学习成本 | Dart 一门语言 | ArkTS + 鸿蒙 API |
| 社区资源 | 全球活跃 | 国内为主 |
关键代码——main.dart 入口:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Step 1: Hive CE 初始化
await Hive.initFlutter();
// Step 2: 设置持久化
final settings = AppSettings();
await settings.init();
// Step 3: 情绪存储
final moodStorage = MoodStorage();
await moodStorage.init();
// 启动
runApp(EBrufenApp(settings: settings, moodStorage: moodStorage));
}
收益:
- 代码 100% Dart,没有 Kotlin/Swift/ArkTS 平台通道
- 未来可零成本编译到 Android/iOS
- Material 3 提供了完整的设计语言,无需单独设计
决策 2:为什么是 ChangeNotifier 而非 Provider / Bloc / Riverpod?
背景:Flutter 状态管理方案众多。E-Brufen 选择了最轻量的原生方案。
多方案对比:
| 方案 | 依赖 | 模板代码 | 学习曲线 | 适用规模 |
|---|---|---|---|---|
| ChangeNotifier | 零(Flutter 内置) | 极少 | 极低 | 小型应用 |
| Provider | provider 包 |
中等(context.read<T>()) |
低 | 中小型 |
| Bloc | flutter_bloc |
大量(Event + State + Bloc) | 高 | 中大型 |
| Riverpod | riverpod |
中等 | 中 | 中大型 |
E-Brufen 的实际情况:
- 5 个页面,2 个数据源(MoodStorage + AppSettings)
- 状态变更路径简单:用户操作 → 数据更新 → UI 刷新
- 不需要跨层级传递、不需要依赖注入容器
ChangeNotifier 在本项目中的使用模式:
// 数据层:继承 ChangeNotifier
class MoodStorage extends ChangeNotifier {
Future<int> insert(MoodEntry entry) async {
await _box?.put(id, jsonEncode(data));
notifyListeners(); // ← 通知所有监听者
return id;
}
}
// UI 层:注册监听
class _DiaryPageState extends State<DiaryPage> {
void initState() {
super.initState();
widget.moodStorage.addListener(_loadMoods); // ← 注册回调
_loadMoods();
}
void _loadMoods() {
setState(() {
_allMoods = widget.moodStorage.getAll(); // ← 重新读取
});
}
void dispose() {
widget.moodStorage.removeListener(_loadMoods); // ← 清理
super.dispose();
}
}
为什么不过度设计:
- Provider 的
context.read<T>()模板代码远超本项目的复杂度收益 - Bloc 的 Event/State/Bloc 三层抽象对 2000 行代码是过度架构
- 原生
addListener+notifyListeners模式零依赖、零学习成本、完全可控
决策 3:为什么是 Hive CE 而非 SQLite?
背景:Flutter 生态中 SQFlite 是最常见的本地存储方案,但它依赖原生 SQLite 库。
关键对比:
| 维度 | Hive CE | SQFlite |
|---|---|---|
| 实现方式 | 纯 Dart(零原生依赖) | Dart FFI + 原生 SQLite .so |
| 鸿蒙兼容 | 完全兼容 | 不兼容(鸿蒙 Flutter 引擎无原生 SQLite) |
| 数据模型 | 键值对(Box) | 关系型表 |
| 查询能力 | 手动遍历 + 过滤 | SQL 查询 |
| 读写速度 | 快(直接序列化) | 中(SQL 解析开销) |
| 类型安全 | 手动序列化 | 有限(需手写映射) |
| 迁移 | 轻量 | 需要 migration 脚本 |
Hive CE 在本项目中的使用:
// settings Box —— 简单键值对
class AppSettings {
Box? _box;
Future<void> init() async {
_box = await Hive.openBox('settings');
}
String get selectedScene =>
_box?.get('selectedScene', defaultValue: '雨中办公') ?? '雨中办公';
set selectedScene(String v) => _box?.put('selectedScene', v);
}
// moods Box —— JSON 字符串值
class MoodStorage extends ChangeNotifier {
static const _boxName = 'moods';
Box? _box;
int _nextId = 1;
Future<int> insert(MoodEntry entry) async {
final id = _nextId++;
final data = entry.toJson();
data['id'] = id;
await _box?.put(id, jsonEncode(data)); // 以 JSON 字符串存储
notifyListeners();
return id;
}
}
为什么不用 SQLite:
- 鸿蒙 Flutter 引擎不提供原生 SQLite 支持,SQFlite 直接无法运行
- E-Brufen 的数据结构天然适合键值模型:情绪记录以 ID 为键,设置以字符串为键
- 无 JOIN 需求、无复杂关联查询 —— 遍历过滤即可满足所有业务需求
决策 4:为什么离线?
决策不仅仅关乎技术,更关乎产品哲学。
离线架构的含义:
传统在线应用:
用户数据 → 服务器 → 数据库 → API 返回
风险: 隐私泄露、服务器成本、合规负担
E-Brufen 离线应用:
用户数据 → Hive CE → 设备本地文件
特点: 零网络权限、零服务器、数据完全由用户掌控
检查 ohos/AppScope/app.json5 中的权限配置 —— 没有 ohos.permission.INTERNET,也没有任何网络相关权限声明。
三大收益:
| 收益 | 说明 |
|---|---|
| 隐私安全 | 情绪数据极其私密,不出设备 = 用户 100% 掌控 |
| 零运营成本 | 无服务器、无数据库、无带宽费用 |
| 零合规风险 | 不收集、不传输、不存储用户数据到云端,符合最严格的隐私法规 |
| 离线可用 | 任何时候都能使用,不依赖网络连接 |
决策 5:为什么程序化生成音频 / 图标?
背景:独立开发者常见困境 —— 没有设计师、没有音频素材库、也不想引入外部版权问题。
E-Brufen 的解法:代码即资源。
程序化生成的范围:
| 资源类型 | 生成方式 | 工具 |
|---|---|---|
| 应用图标 | Dart 代码绘制 → PNG 导出 | dart:ui Canvas + ui.Image.toByteData() |
| 呼吸引导 | 数学函数生成(正弦波、包络) | Dart dart:math |
| 视觉脉冲 | 动画控制器 + 数学插值 | Flutter AnimationController |
设计哲学:
- 可复现:任何开发者拉取代码即可生成完全一致的资源
- 可定制:修改参数即可调整颜色、大小、频率
- 零版权风险:所有资源由代码生成,无外部素材依赖
- 版本可控:生成脚本纳入 Git,资源变更可追溯
实际效果:运行 dart run scripts/generate_icons.dart 即可在 ohos/AppScope/resources/base/media/ 下生成所有需要的图标文件(app_icon.png、1.png 等),完全自动化,无需任何外部图片工具。
决策 6:为什么没有音频播放插件?
背景:白噪音放松功能通常需要音频播放。E-Brufen 的 SoundscapePage 当前是纯视觉体验。
原因分析:
| 因素 | 现状 |
|---|---|
| 鸿蒙 Flutter 音频插件 | 生态不成熟,audioplayers 等主流包不支持鸿蒙 |
| 纯 Dart 音频方案 | dart:ffi 方式在鸿蒙上受限 |
| 应用定位 | E-Brufen 定位为 “小而美” 的 MVP,功能优先级明确 |
SoundscapePage 的当前实现:
// 纯视觉放松体验(无音频依赖)
class SoundscapePage extends StatefulWidget {
// 场景选择 → 定时器 → 脉冲动画
// 4 个场景:海边入眠 / 雨中办公 / 森林冥想 / 篝火夜读
// 脉冲动画: AnimatedBuilder + AnimationController + 数学缩放
}
规划路线:
- 短期(当前版本):视觉脉冲动画 + 沉浸式 UI 作为放松入口
- 中期(下一版):自研纯 Dart WAV 合成(用数学算法生成雨声/海浪等环境音)
- 长期:待鸿蒙 Flutter 音频插件生态成熟后集成原生播放能力
四、技术决策总结矩阵
| # | 决策 | 选择 | 替代方案 | 核心原因 |
|---|---|---|---|---|
| 1 | 跨平台框架 | Flutter | ArkTS / React Native | 鸿蒙引擎可用、跨平台潜力、Dart 生态 |
| 2 | 状态管理 | ChangeNotifier | Provider / Bloc / Riverpod | 应用规模小、零依赖、无模板代码 |
| 3 | 本地存储 | Hive CE | SQFlite / SharedPreferences | 纯 Dart 实现、鸿蒙兼容、键值够用 |
| 4 | 网络策略 | 完全离线 | REST API / Firebase | 隐私优先、零成本、零合规风险 |
| 5 | 资源策略 | 程序化生成 | 手动设计 / 购买素材 | 可复现、可定制、零版权 |
| 6 | 音频播放 | 暂不使用 | audioplayers / just_audio | 鸿蒙插件生态不成熟、MVP 优先级 |
五、系列文章导航(完整 50 篇)
本系列共 50 篇文章,覆盖鸿蒙 Flutter 开发全流程:
第一篇:环境搭建与入门(Post 01-10)
| 编号 | 文章标题 | 核心内容 |
|---|---|---|
| 01 | 鸿蒙 Flutter 开发环境搭建 | DevEco Studio + Flutter SDK + 模拟器配置 |
| 02 | 创建第一个鸿蒙 Flutter 项目 | flutter create + 项目结构解析 |
| 03 | Flutter 项目目录结构详解 | lib / ohos / android / ios 目录职责 |
| 04 | Dart 基础速览 | 变量、函数、类、异步、空安全 |
| 05 | Flutter Widget 核心概念 | StatelessWidget / StatefulWidget / BuildContext |
| 06 | Material 3 主题系统入门 | ColorScheme / ThemeData / 品牌色定制 |
| 07 | Hive CE 安装与初始化 | hive_ce + hive_ce_flutter 依赖引入与 Box 打开 |
| 08 | 鸿蒙签名与证书配置 | .p12 / .p7b / .cer 证书链,签名流程 |
| 09 | 真机调试与 HAP 安装 | DevEco Studio 连接真机、HAP 构建与部署 |
| 10 | 技术选型全景(本文) | 架构总览、六大决策、学习路线图 |
第二篇:核心功能实现(Post 11-20)
| 编号 | 文章标题 | 核心内容 |
|---|---|---|
| 11 | 情绪数据模型设计 | MoodType 枚举、MoodEntry 类、序列化 |
| 12 | MoodStorage 存储层实现 | ChangeNotifier + Hive CE CRUD 完整实现 |
| 13 | AppSettings 设置持久化 | Hive Box 键值存取、默认值策略 |
| 14 | 首页 UI 构建 | HomePage 布局、问候语、功能卡片 |
| 15 | HomeCard 组件设计 | 可复用渐变卡片、emoji + 标题 + 副标题 |
| 16 | 情绪日记 —— 记录 Tab | MoodPicker 集成、日期选择、保存逻辑 |
| 17 | 情绪日记 —— 时间线 Tab | 按月分组、ListView、详情 BottomSheet |
| 18 | 情绪日记 —— 统计 Tab | MoodChart 周柱状图、总结文案生成 |
| 19 | 情绪日记 CRUD 完整实现 | 编辑、删除、SnackBar 反馈 |
| 20 | 今日速记功能 | HomePage 快速记录、Tooltip、错误处理 |
第三篇:架构与状态管理(Post 21-30)
| 编号 | 文章标题 | 核心内容 |
|---|---|---|
| 21 | ChangeNotifier 模式深入 | addListener / notifyListeners 生命周期 |
| 22 | 数据流向全景图 | UI → Widget → State → Storage 单向数据流 |
| 23 | main.dart 启动流程剖析 | 分步初始化、错误处理、_ErrorApp 降级 |
| 24 | 页面间导航设计 | Navigator.push / MaterialPageRoute / 传参模式 |
| 25 | 组件树与 Widget 复用策略 | HomeCard / MoodPicker / MoodChart 抽取原则 |
| 26 | 状态提升与数据共享 | MoodStorage 跨页面共享、单例模式 |
| 27 | 错误处理与降级策略 | FlutterError.onError / try-catch / 优雅降级 UI |
| 28 | 生命周期管理 | initState / dispose / mounted 检查 |
| 29 | 性能优化实践 | const 构造器、ListView.builder、避免不必要的 rebuild |
| 30 | 架构决策回顾与反思 | 技术债盘点、未来演进方向 |
第四篇:动画、UI 与资源生成(Post 31-42)
| 编号 | 文章标题 | 核心内容 |
|---|---|---|
| 31 | AppTheme 全局主题设计 | 品牌色、渐变、Material 3 ThemeData |
| 32 | MoodPicker 动画实现 | AnimatedScale、选中高亮、GestureDetector |
| 33 | MoodChart 自绘柱状图 | 周数据聚合、颜色映射、AnimatedContainer |
| 34 | BreathingCircle 呼吸动画 | AnimationController + Timer 联动、缩放 + 透明度 |
| 35 | 呼吸模式设计(4-7-8 / 盒式 / 放松) | BreathePattern 数据模型、阶段切换逻辑 |
| 36 | 呼吸练习完整流程 | 模式选择 → 开始 → 暂停/继续 → 完成弹窗 |
| 37 | SoundscapePage 视觉脉冲 | AnimatedBuilder + AnimationController 数学缩放 |
| 38 | 场景选择与定时器 | ChoiceChip、Timer 倒计时、触觉反馈 |
| 39 | 程序化应用图标生成 | dart:ui Canvas 绘制 → PNG 导出脚本 |
| 40 | 程序化音频合成原理 | 正弦波、白噪声、包络生成数学基础 |
| 41 | 自定义动画组件开发总结 | AnimationController / Tween / AnimatedBuilder 模式 |
| 42 | Material 3 主题定制深入 | ColorScheme.fromSeed / 组件主题覆盖 |
第五篇:测试、发布与总结(Post 43-50)
| 编号 | 文章标题 | 核心内容 |
|---|---|---|
| 43 | 单元测试实践 | MoodEntry 序列化测试、MoodStorage CRUD 测试 |
| 44 | Widget 测试入门 | pumpWidget / find / tap 基础用法 |
| 45 | 集成测试与 Golden 测试 | 页面截图对比、完整流程测试 |
| 46 | 鸿蒙 HAP 构建配置 | build-profile.json5、签名配置、版本号管理 |
| 47 | AppGallery 发布流程 | 应用信息填写、审核要点、元数据准备 |
| 48 | CI/CD 流水线搭建 | GitHub Actions / 自动构建 / 自动签名 |
| 49 | 项目复盘与经验总结 | 技术决策回顾、踩坑记录、最佳实践 |
| 50 | 系列终章:从零到发布的鸿蒙 Flutter 之旅 | 完整学习路径、开源计划、社区贡献 |
六、学习路线图
按角色和阶段规划的学习路径:
阶段一:快速入门(Post 01-05,约 3 天)
目标:跑起第一个鸿蒙 Flutter 应用
01 环境搭建 ──→ 02 创建项目 ──→ 03 目录结构
│
└──→ 04 Dart 基础 ──→ 05 Widget 概念
关键产出:DevEco Studio 可用、模拟器运行成功、理解 Widget 树
阶段二:基础建设(Post 06-10,约 2 天)
目标:理解项目基础设施
06 Material 3 ──→ 07 Hive CE ──→ 08 签名配置
│
09 真机调试 ←────────────────────────────┘
│
└──→ 10 技术选型全景(本文)
关键产出:主题定制能力、本地存储可用、签名配置完成
阶段三:核心功能(Post 11-20,约 5 天)
目标:实现情绪日记完整功能
11 数据模型 ──→ 12 MoodStorage ──→ 14 首页 UI
│ │
13 AppSettings ←────┘ │
│
15 HomeCard ──→ 16 记录Tab ──→ 17 时间线Tab
│
18 统计Tab ←──── 19 CRUD完整 ←── 20 今日速记
关键产出:完整的情绪日记 CRUD 功能、带统计图表
阶段四:架构深入(Post 21-30,约 4 天)
目标:理解架构设计思想
21 ChangeNotifier ──→ 22 数据流全景 ──→ 23 main.dart 剖析
│
24 页面导航 ←── 25 组件复用 ←── 26 状态提升
│
27 错误处理 ──→ 28 生命周期 ──→ 29 性能优化 ──→ 30 架构回顾
关键产出:状态管理能力、架构设计思维、性能优化意识
阶段五:动画与资源(Post 31-42,约 6 天)
目标:掌握动画开发和资源生成
31 AppTheme ──→ 32 MoodPicker动画 ──→ 33 MoodChart自绘
│
34 呼吸动画 ──→ 35 呼吸模式 ──→ 36 呼吸流程 │
│
37 视觉脉冲 ──→ 38 场景定时器 ──→ 39 图标生成
│
40 音频合成 ──→ 41 动画总结 ←── 42 M3深入
关键产出:AnimationController 熟练使用、程序化资源生成能力
阶段六:测试与发布(Post 43-50,约 5 天)
目标:完成测试、构建与发布
43 单元测试 ──→ 44 Widget测试 ──→ 45 集成测试
│
46 HAP构建 ──→ 47 发布流程 ←──────────┘
│
└──→ 48 CI/CD ──→ 49 项目复盘 ──→ 50 系列终章
关键产出:完整测试覆盖、HAP 构建能力、AppGallery 发布经验
总体学习路径图
┌───────────────────────────────────────────────────────┐
│ E-Brufen 学习路线图 │
│ │
│ 阶段一 ────→ 阶段二 ────→ 阶段三 ────→ 阶段四 │
│ 快速入门 基础建设 核心功能 架构深入 │
│ (3天) (2天) (5天) (4天) │
│ │ │ │ │ │
│ └────────────┴────────────┴────────────┘ │
│ │ │
│ ↓ │
│ 阶段五 ────→ 阶段六 │
│ 动画资源 测试发布 │
│ (6天) (5天) │
│ │
│ 总计约 25 天,完整覆盖鸿蒙 Flutter 开发全流程 │
└───────────────────────────────────────────────────────┘
七、从本项目中你可以学到的技能清单
硬技能
| 分类 | 具体技能 | 对应文章 |
|---|---|---|
| 框架 | Flutter Widget 体系、StatefulWidget 生命周期 | 05, 28 |
| 状态管理 | ChangeNotifier + addListener 模式 | 21, 22, 26 |
| 本地存储 | Hive CE Box 操作、JSON 序列化 | 07, 12, 13 |
| UI 设计 | Material 3 主题定制、品牌色系统 | 06, 31, 42 |
| 动画 | AnimationController、Tween、AnimatedBuilder | 32, 34, 37, 41 |
| 自绘 | 自定义柱状图、Canvas 绘制图标 | 33, 39 |
| 导航 | Navigator 2.0、页面传参 | 24 |
| 平台 | 鸿蒙签名证书、HAP 构建、hvigor | 08, 46 |
| 测试 | 单元测试、Widget 测试、集成测试 | 43, 44, 45 |
| CI/CD | GitHub Actions 自动化构建 | 48 |
| 发布 | AppGallery 上架流程 | 47 |
软技能
| 技能 | 说明 |
|---|---|
| 技术选型能力 | 理解"够用就好"原则,避免过度架构 |
| 离线优先思维 | 隐私设计、零依赖外部服务 |
| 资源策略 | 程序化生成 > 手动制作 > 购买素材 |
| 渐进增强 | MVP 先跑通核心闭环,再逐步完善 |
| 跨平台意识 | 写一套代码,考虑多平台兼容性 |
八、项目文件结构速查

lib/
├── main.dart # 入口:初始化 → 启动应用
├── theme/
│ └── app_theme.dart # 品牌色、渐变、Material 3 主题
├── models/
│ └── mood_entry.dart # MoodType 枚举 + MoodEntry 数据类
├── data/
│ ├── mood_storage.dart # 情绪 CRUD(ChangeNotifier)
│ └── settings.dart # 设置持久化(plain Dart)
├── pages/
│ ├── home_page.dart # 首页(问候 + 3 卡片 + 今日速记)
│ ├── diary/
│ │ └── diary_page.dart # 情绪日记(3 Tab)
│ ├── breathe/
│ │ └── breathe_page.dart # 呼吸练习(模式 + 动画)
│ └── soundscape/
│ └── soundscape_page.dart # 白噪音放松(视觉脉冲)
└── widgets/
├── home_card.dart # 可复用渐变功能卡片
├── mood_picker.dart # 5 表情选择器
├── mood_chart.dart # 周情绪柱状图
└── breathing_circle.dart # 呼吸动画球 + 模式定义
小结
E-Brufen 是一个 “小而美” 的项目 —— 代码量不到 2000 行,13 个 Dart 源文件,仅 2 个核心依赖,但覆盖了鸿蒙 Flutter 开发的几乎所有关键环节:
- 完整的技术架构:从 UI 到存储的五层分层架构
- 务实的选型决策:每一项选择都基于实际约束而非潮流
- 系统的知识体系:50 篇文章覆盖从入门到发布的完整路径
- 可复现的工程实践:代码即资源,拉取即运行
作者简介:E-Brufen Dev,Flutter & 鸿蒙开发者,专注于跨平台移动应用开发与心理健康数字化。项目托管于 AtomGit,欢迎 Star 和 Issue 讨论。
系列文章:本文为《鸿蒙 Flutter 实战》系列第 10 篇。查看完整系列请访问项目文档目录。
更多推荐


所有评论(0)