开源鸿蒙跨平台训练营DAY13:Flutter for OpenHarmony收藏功能实现
本文介绍了开源鸿蒙跨平台社区中实现多页面收藏功能的技术方案。通过Provider全局状态管理和shared_preferences本地存储,完成了首页、列表页、分类页与收藏页的实时同步,实现点击变色、数据持久化、跨页状态一致等功能。文章详细说明了7步实现流程,包括依赖准备、模型标准化、全局状态封装与注入等关键步骤,并针对跨页同步、序列化、重复识别等难点提供了解决方案。最后总结了状态修改通知、持久化
##欢迎加入开源鸿蒙跨平台社区
https://openharmonycrossplatform.csdn.net
#学习资料:
可参考https://bxming.blog.csdn.net/article/details/156203132
https://blog.csdn.net/tyty0214/article/details/157311564?fromshare=blogdetail&sharetype=blogdetail&sharerId=157311564&sharerefer=PC&sharesource=tyty0214&sharefrom=from_link
https://blog.csdn.net/tyty0214/article/details/157379995
https://blog.csdn.net/tyty0214/article/details/157442068
https://blog.csdn.net/tyty0214/article/details/157500747
https://blog.csdn.net/tyty0214/article/details/157825622
https://blog.csdn.net/tyty0214/article/details/157831127
#具体流程:
##一、核心功能目标
- 多页面实时同步:首页、列表页、分类页收藏按钮点击即变色反馈
- 我的收藏页动态更新:无需刷新,自动显示 / 移除收藏项
- 本地持久化:重启 APP 后收藏状态不丢失
- 跨页状态一致:同一蘑菇在任意页面收藏状态统一
##二、实现核心流程(7 步)
###1. 依赖准备
- 核心依赖:
provider(全局状态管理)、shared_preferences(本地存储) - 辅助依赖:
pull_to_refresh(下拉刷新)、dio(兼容原有网络请求) - 配置
pubspec.yaml后执行flutter pub get安装
###2. 模型标准化
- 完善
MushroomModel,含id(唯一标识)、name等核心字段 - 重写
==和hashCode,按id判断唯一性,避免重复收藏 - 新增
toJson()(转 JSON 存储)、fromJson()(接口解析)、fromLocalJson()(本地解析)方法
###3. 全局状态封装(CollectProvider)
- 核心职责:管理收藏列表、本地存储、状态通知
- 关键方法:
init():APP 启动时读取本地 JSON,解析为收藏列表toggleCollect():判断收藏状态,更新内存列表→序列化存储→调用notifyListeners()通知页面refreshCollect():手动刷新收藏数据
###4. 全局状态注入
- 改造
main.dart,初始化CollectProvider并await init()加载本地数据 - 用
MultiProvider全局注册CollectProvider和ThemeProvider - 确保所有页面通过
MainTabBar聚合,处于状态作用域内
###5. 多页面集成
- 收藏按钮(首页 / 列表页 / 分类页):用
Consumer<CollectProvider>包裹 Item,绑定toggleCollect(),按id判断状态并切换图标颜色 - 我的收藏页:
Consumer监听列表变化,复用toggleCollect()实现删除,添加下拉刷新
###6. 代码提交
- 拉取远程代码:
git pull origin main(避冲突) - 添加文件:
git add . - 本地提交:
git commit -m "feat: 实现收藏跨页同步+持久化" - 推送远程:
git push origin main - 冲突处理:编辑冲突文件→
git add .→重新提交推送
##三、关键难点与解决方案
###难点 1:跨页同步不及时
- 表现:A 页面收藏后,B 页面状态未更新
- 方案:放弃局部状态,统一通过
CollectProvider获取;用Consumer包裹组件,实时监听刷新
###难点 2:序列化 / 反序列化失败
- 表现:重启 APP 收藏列表空白,报格式错误
- 方案:模型方法处理空值默认值;用标准
jsonEncode/jsonDecode;捕获异常初始化空列表
###难点 3:蘑菇识别重复
- 表现:重复收藏或取消失效
- 方案:重写
==和hashCode,按id判断唯一性
###难点 4:Provider 作用域失效
- 表现:部分页面无法获取状态,报错找不到 Provider
- 方案:
MultiProvider包裹根MaterialApp;仅保留一个MaterialApp;所有页面通过MainTabBar聚合
##四、实战踩坑记录
| 问题 | 表现 | 解决方法 |
|---|---|---|
| 收藏按钮不变色 | 点击无反馈,无日志 | 检查Consumer包裹、notifyListeners()调用、id判断逻辑 |
| 我的收藏页空白 | 收藏后无数据显示 | 验证init()异步执行、存储键名一致、字段映射无拼写错误 |
| 重启状态丢失 | 重启后收藏为空 | 确认prefs.setString()调用、JSON 格式正确、清除旧缓存测试 |
| 主题切换报错 | 提示darkMode isn't defined |
统一字段名为themeMode、传入ThemeMode参数、删除无用导入 |
| 列表滑动状态错乱 | 滑动后图标显示错误 | 基于全局状态判断、验证模型重写、不缓存状态 |
| 多页面操作异常 | 重复项 / 无法移除 | init()加锁防并发、先更内存再存本地、按id操作列表 |
##五、关键注意事项
- 状态修改后必须调用
notifyListeners() - 持久化测试需重启 APP,避免热重载
- 初始化顺序:绑定 Flutter→初始化 Provider→启动 APP
- 全场景处理空值,避免崩溃
- 提交前先拉取远程代码,备注规范


#DAY13小结:
本次功能核心是「全局单一数据源 + 实时通知 + 本地持久化」,通过Provider实现跨页同步,shared_preferences完成数据留存,标准化模型保障逻辑准确性。开发难点集中在状态同步和存储兼容,解决关键在于放弃局部状态、统一依赖全局 Provider、规范数据序列化流程。最终实现了点击即反馈、跨页即同步、重启即留存的预期效果,兼顾了功能稳定性和可维护性。
更多推荐







所有评论(0)