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 行 Dart13 个源文件页面数4 个主页面 首页依赖数量仅hive_cehive_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 通过其鸿蒙引擎提供了一条跨平台路径。决策理由维度FlutterArkTS 原生跨平台潜力Android / iOS / Web / 鸿蒙一套代码仅鸿蒙组件生态Material 3 开箱即用需从零搭建热重载支持秒级不支持学习成本Dart 一门语言ArkTS 鸿蒙 API社区资源全球活跃国内为主关键代码——main.dart 入口voidmain()async{WidgetsFlutterBinding.ensureInitialized();// Step 1: Hive CE 初始化awaitHive.initFlutter();// Step 2: 设置持久化finalsettingsAppSettings();awaitsettings.init();// Step 3: 情绪存储finalmoodStorageMoodStorage();awaitmoodStorage.init();// 启动runApp(EBrufenApp(settings:settings,moodStorage:moodStorage));}收益代码 100% Dart没有 Kotlin/Swift/ArkTS 平台通道未来可零成本编译到 Android/iOSMaterial 3 提供了完整的设计语言无需单独设计决策 2为什么是 ChangeNotifier 而非 Provider / Bloc / Riverpod背景Flutter 状态管理方案众多。E-Brufen 选择了最轻量的原生方案。多方案对比方案依赖模板代码学习曲线适用规模ChangeNotifier零Flutter 内置极少极低小型应用Providerprovider包中等context.readT()低中小型Blocflutter_bloc大量Event State Bloc高中大型Riverpodriverpod中等中中大型E-Brufen 的实际情况5 个页面2 个数据源MoodStorage AppSettings状态变更路径简单用户操作 → 数据更新 → UI 刷新不需要跨层级传递、不需要依赖注入容器ChangeNotifier 在本项目中的使用模式// 数据层继承 ChangeNotifierclassMoodStorageextendsChangeNotifier{Futureintinsert(MoodEntryentry)async{await_box?.put(id,jsonEncode(data));notifyListeners();// ← 通知所有监听者returnid;}}// UI 层注册监听class_DiaryPageStateextendsStateDiaryPage{overridevoidinitState(){super.initState();widget.moodStorage.addListener(_loadMoods);// ← 注册回调_loadMoods();}void_loadMoods(){setState((){_allMoodswidget.moodStorage.getAll();// ← 重新读取});}overridevoiddispose(){widget.moodStorage.removeListener(_loadMoods);// ← 清理super.dispose();}}为什么不过度设计Provider 的context.readT()模板代码远超本项目的复杂度收益Bloc 的 Event/State/Bloc 三层抽象对 2000 行代码是过度架构原生addListenernotifyListeners模式零依赖、零学习成本、完全可控决策 3为什么是 Hive CE 而非 SQLite背景Flutter 生态中 SQFlite 是最常见的本地存储方案但它依赖原生 SQLite 库。关键对比维度Hive CESQFlite实现方式纯 Dart零原生依赖Dart FFI 原生 SQLite .so鸿蒙兼容完全兼容不兼容鸿蒙 Flutter 引擎无原生 SQLite数据模型键值对Box关系型表查询能力手动遍历 过滤SQL 查询读写速度快直接序列化中SQL 解析开销类型安全手动序列化有限需手写映射迁移轻量需要 migration 脚本Hive CE 在本项目中的使用// settings Box —— 简单键值对classAppSettings{Box?_box;Futurevoidinit()async{_boxawaitHive.openBox(settings);}StringgetselectedScene_box?.get(selectedScene,defaultValue:雨中办公)??雨中办公;setselectedScene(Stringv)_box?.put(selectedScene,v);}// moods Box —— JSON 字符串值classMoodStorageextendsChangeNotifier{staticconst_boxNamemoods;Box?_box;int _nextId1;Futureintinsert(MoodEntryentry)async{finalid_nextId;finaldataentry.toJson();data[id]id;await_box?.put(id,jsonEncode(data));// 以 JSON 字符串存储notifyListeners();returnid;}}为什么不用 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:uiCanvas ui.Image.toByteData()呼吸引导数学函数生成正弦波、包络Dartdart:math视觉脉冲动画控制器 数学插值FlutterAnimationController设计哲学可复现任何开发者拉取代码即可生成完全一致的资源可定制修改参数即可调整颜色、大小、频率零版权风险所有资源由代码生成无外部素材依赖版本可控生成脚本纳入 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 的当前实现// 纯视觉放松体验无音频依赖classSoundscapePageextendsStatefulWidget{// 场景选择 → 定时器 → 脉冲动画// 4 个场景海边入眠 / 雨中办公 / 森林冥想 / 篝火夜读// 脉冲动画: AnimatedBuilder AnimationController 数学缩放}规划路线短期当前版本视觉脉冲动画 沉浸式 UI 作为放松入口中期下一版自研纯 Dart WAV 合成用数学算法生成雨声/海浪等环境音长期待鸿蒙 Flutter 音频插件生态成熟后集成原生播放能力四、技术决策总结矩阵#决策选择替代方案核心原因1跨平台框架FlutterArkTS / React Native鸿蒙引擎可用、跨平台潜力、Dart 生态2状态管理ChangeNotifierProvider / Bloc / Riverpod应用规模小、零依赖、无模板代码3本地存储Hive CESQFlite / 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 项目结构解析03Flutter 项目目录结构详解lib / ohos / android / ios 目录职责04Dart 基础速览变量、函数、类、异步、空安全05Flutter Widget 核心概念StatelessWidget / StatefulWidget / BuildContext06Material 3 主题系统入门ColorScheme / ThemeData / 品牌色定制07Hive CE 安装与初始化hive_cehive_ce_flutter依赖引入与 Box 打开08鸿蒙签名与证书配置.p12 / .p7b / .cer 证书链签名流程09真机调试与 HAP 安装DevEco Studio 连接真机、HAP 构建与部署10技术选型全景本文架构总览、六大决策、学习路线图第二篇核心功能实现Post 11-20编号文章标题核心内容11情绪数据模型设计MoodType 枚举、MoodEntry 类、序列化12MoodStorage 存储层实现ChangeNotifier Hive CE CRUD 完整实现13AppSettings 设置持久化Hive Box 键值存取、默认值策略14首页 UI 构建HomePage 布局、问候语、功能卡片15HomeCard 组件设计可复用渐变卡片、emoji 标题 副标题16情绪日记 —— 记录 TabMoodPicker 集成、日期选择、保存逻辑17情绪日记 —— 时间线 Tab按月分组、ListView、详情 BottomSheet18情绪日记 —— 统计 TabMoodChart 周柱状图、总结文案生成19情绪日记 CRUD 完整实现编辑、删除、SnackBar 反馈20今日速记功能HomePage 快速记录、Tooltip、错误处理第三篇架构与状态管理Post 21-30编号文章标题核心内容21ChangeNotifier 模式深入addListener / notifyListeners 生命周期22数据流向全景图UI → Widget → State → Storage 单向数据流23main.dart 启动流程剖析分步初始化、错误处理、_ErrorApp 降级24页面间导航设计Navigator.push / MaterialPageRoute / 传参模式25组件树与 Widget 复用策略HomeCard / MoodPicker / MoodChart 抽取原则26状态提升与数据共享MoodStorage 跨页面共享、单例模式27错误处理与降级策略FlutterError.onError / try-catch / 优雅降级 UI28生命周期管理initState / dispose / mounted 检查29性能优化实践const 构造器、ListView.builder、避免不必要的 rebuild30架构决策回顾与反思技术债盘点、未来演进方向第四篇动画、UI 与资源生成Post 31-42编号文章标题核心内容31AppTheme 全局主题设计品牌色、渐变、Material 3 ThemeData32MoodPicker 动画实现AnimatedScale、选中高亮、GestureDetector33MoodChart 自绘柱状图周数据聚合、颜色映射、AnimatedContainer34BreathingCircle 呼吸动画AnimationController Timer 联动、缩放 透明度35呼吸模式设计4-7-8 / 盒式 / 放松BreathePattern 数据模型、阶段切换逻辑36呼吸练习完整流程模式选择 → 开始 → 暂停/继续 → 完成弹窗37SoundscapePage 视觉脉冲AnimatedBuilder AnimationController 数学缩放38场景选择与定时器ChoiceChip、Timer 倒计时、触觉反馈39程序化应用图标生成dart:ui Canvas 绘制 → PNG 导出脚本40程序化音频合成原理正弦波、白噪声、包络生成数学基础41自定义动画组件开发总结AnimationController / Tween / AnimatedBuilder 模式42Material 3 主题定制深入ColorScheme.fromSeed / 组件主题覆盖第五篇测试、发布与总结Post 43-50编号文章标题核心内容43单元测试实践MoodEntry 序列化测试、MoodStorage CRUD 测试44Widget 测试入门pumpWidget / find / tap 基础用法45集成测试与 Golden 测试页面截图对比、完整流程测试46鸿蒙 HAP 构建配置build-profile.json5、签名配置、版本号管理47AppGallery 发布流程应用信息填写、审核要点、元数据准备48CI/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, 13UI 设计Material 3 主题定制、品牌色系统06, 31, 42动画AnimationController、Tween、AnimatedBuilder32, 34, 37, 41自绘自定义柱状图、Canvas 绘制图标33, 39导航Navigator 2.0、页面传参24平台鸿蒙签名证书、HAP 构建、hvigor08, 46测试单元测试、Widget 测试、集成测试43, 44, 45CI/CDGitHub Actions 自动化构建48发布AppGallery 上架流程47软技能技能说明技术选型能力理解够用就好原则避免过度架构离线优先思维隐私设计、零依赖外部服务资源策略程序化生成 手动制作 购买素材渐进增强MVP 先跑通核心闭环再逐步完善跨平台意识写一套代码考虑多平台兼容性八、项目文件结构速查lib/ ├── main.dart # 入口初始化 → 启动应用 ├── theme/ │ └── app_theme.dart # 品牌色、渐变、Material 3 主题 ├── models/ │ └── mood_entry.dart # MoodType 枚举 MoodEntry 数据类 ├── data/ │ ├── mood_storage.dart # 情绪 CRUDChangeNotifier │ └── 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 篇文章覆盖从入门到发布的完整路径可复现的工程实践代码即资源拉取即运行项目源码https://gitcode.com/PengXiansheng/E-Brufen作者简介E-Brufen DevFlutter 鸿蒙开发者专注于跨平台移动应用开发与心理健康数字化。项目托管于 AtomGit欢迎 Star 和 Issue 讨论。系列文章本文为《鸿蒙 Flutter 实战》系列第 10 篇。查看完整系列请访问项目文档目录。