Flutter for HarmonyOS 开发学习 DAY12-13:应用浏览历史功能
在游戏应用中,浏览历史可帮助用户快速找到最近查看的游戏。本文介绍如何在 Flutter HarmonyOS 应用中实现浏览历史,包括在线游戏和经典游戏的分类管理、自动记录、持久化存储等功能。// 游戏ID,用于唯一标识// 游戏标题,用于显示// 缩略图URL,用于展示// 游戏类型:'online' 或 'classic'// 浏览时间,用于排序和显示// 构造函数和JSON序列化方法完整的浏览
·
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
一、前言
在游戏应用中,浏览历史可帮助用户快速找到最近查看的游戏。本文介绍如何在 Flutter HarmonyOS 应用中实现浏览历史,包括在线游戏和经典游戏的分类管理、自动记录、持久化存储等功能。
二、需求分析
2.1 功能需求
- 自动记录:用户点击游戏时自动记录浏览历史
- 分类管理:区分在线游戏和经典游戏
- 历史查看:在个人中心查看浏览历史
- 数据管理:支持删除单条、按类型清除、全部清除
- 快速跳转:点击历史记录可快速打开游戏
2.2 技术挑战
- 平台兼容性:HarmonyOS 上文件存储路径获取
- 数据持久化:JSON 文件存储,兼容性处理
- 去重机制:相同游戏只保留最新记录
- 性能优化:限制记录数量,避免数据过大
- 用户体验:空状态、加载状态、错误处理
三、架构设计
3.1 数据模型设计
- 核心字段:游戏ID、标题、缩略图、游戏类型、浏览时间
- JSON 序列化:支持持久化与恢复
- 时间格式化:提供友好的时间显示(如“刚刚”“5分钟前”)
3.2 服务层设计
- 存储管理:文件存储 + 内存缓存双重保障
- 初始化流程:获取存储目录、加载历史数据
- CRUD 操作:添加、查询、删除、清除
- 分类查询:按游戏类型筛选
3.3 UI 层设计
- Tab 切换:在线游戏/经典游戏两个标签页
- 列表展示:卡片式布局,显示缩略图、标题、时间
- 交互功能:点击跳转、单条删除、批量清除
- 状态管理:加载、空状态、错误处理
四、核心实现
4.1 数据模型实现
4.1.1 BrowseHistory 模型定义
class BrowseHistory {
final int gameId; // 游戏ID,用于唯一标识
final String gameTitle; // 游戏标题,用于显示
final String thumbnail; // 缩略图URL,用于展示
final String gameType; // 游戏类型:'online' 或 'classic'
final DateTime browseTime; // 浏览时间,用于排序和显示
// 构造函数和JSON序列化方法
}
4.1.2 时间格式化方法
String get formattedBrowseTime {
final now = DateTime.now();
final difference = now.difference(browseTime);
if (difference.inDays > 0) {
return '${difference.inDays}天前';
} else if (difference.inHours > 0) {
return '${difference.inHours}小时前';
} else if (difference.inMinutes > 0) {
return '${difference.inMinutes}分钟前';
} else {
return '刚刚';
}
}
4.2 服务层实现
4.2.1 存储初始化
- Platform Channel 获取目录:优先通过 MethodChannel 获取 HarmonyOS 应用数据目录
- 路径回退机制:失败时尝试常见路径(
/data/storage/el2/base/haps等) - 临时目录兜底:最终回退到系统临时目录
- 自动加载历史:初始化时从文件加载已有数据
4.2.2 添加浏览历史
static Future<void> addHistory(BrowseHistory history) async {
// 1. 去重:移除相同游戏的旧记录
_memoryCache.removeWhere((h) =>
h.gameId == history.gameId && h.gameType == history.gameType
);
// 2. 添加到列表开头(最新在前)
_memoryCache.insert(0, history);
// 3. 限制数量:最多保存100条记录
if (_memoryCache.length > 100) {
_memoryCache.removeRange(100, _memoryCache.length);
}
// 4. 持久化保存
await _saveToFile();
}
要点:
- 去重:相同游戏只保留最新记录
- 排序:新记录插入到列表开头
- 限制:最多100条,避免数据过大
- 持久化:立即保存到文件
4.2.3 分类查询方法
getAllHistory():获取所有浏览历史getOnlineGameHistory():筛选在线游戏(gameType == 'online')getClassicGameHistory():筛选经典游戏(gameType == 'classic')

4.2.4 清除功能实现
clearAllHistory():清空内存缓存并删除文件clearOnlineGameHistory():只清除在线游戏记录clearClassicGameHistory():只清除经典游戏记录deleteHistory():删除单条记录(通过ID、类型、时间匹配)
4.3 UI 层实现
4.3.1 Tab 切换设计
TabBar(
controller: _tabController,
tabs: const [
Tab(icon: Icon(Icons.gamepad), text: '在线游戏'),
Tab(icon: Icon(Icons.stars), text: '经典游戏'),
],
)
- 使用
TabController管理切换 - 两个标签页分别显示不同类型的历史
- 图标区分:游戏手柄(在线)、星星(经典)
4.3.2 历史记录项构建
- 缩略图展示:网络图片加载,失败时显示占位图标
- 信息展示:游戏标题、浏览时间、类型标签
- 交互按钮:删除按钮,支持单条删除
- 点击跳转:点击卡片跳转到对应游戏
4.3.3 点击跳转逻辑
在线游戏:
- 通过游戏ID查找游戏信息
- 尝试打开游戏官网
- 失败时显示URL对话框,支持复制链接
经典游戏:
- 根据游戏标题判断(如“2048”)
- 跳转到对应游戏页面
- 未实现游戏显示开发中提示
4.3.4 清除功能实现
- 清除按钮:AppBar 右上角删除图标
- 智能清除:根据当前Tab清除对应类型的历史
- 确认对话框:危险操作二次确认
- 空状态处理:无历史时显示提示
4.4 集成实现
4.4.1 在线游戏列表集成
Future<void> _openGameWebsite(Game game) async {
// 记录浏览历史
try {
final history = BrowseHistory(
gameId: game.id,
gameTitle: game.title,
thumbnail: game.thumbnail,
gameType: 'online',
browseTime: DateTime.now(),
);
await BrowseHistoryService.addHistory(history);
} catch (e) {
debugPrint('记录浏览历史失败: $e');
}
// 继续打开游戏官网的逻辑...
}
- 在
_openGameWebsite方法开头记录历史 - 使用 try-catch 确保记录失败不影响主流程
- 记录时机:用户点击游戏时立即记录
4.4.2 经典游戏列表集成
onTap: () async {
// 记录浏览历史
try {
final history = BrowseHistory(
gameId: game.id,
gameTitle: game.title,
thumbnail: game.thumbnail,
gameType: 'classic',
browseTime: DateTime.now(),
);
await BrowseHistoryService.addHistory(history);
} catch (e) {
debugPrint('记录浏览历史失败: $e');
}
// 继续游戏跳转逻辑...
}
- 在游戏点击事件中记录历史
- 游戏类型设置为
'classic' - 异步处理,不阻塞UI
4.4.3 主应用初始化
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 初始化浏览历史服务
try {
await BrowseHistoryService.initialize();
} catch (e) {
debugPrint('初始化浏览历史服务失败: $e');
}
runApp(const MyApp());
}
- 应用启动时初始化服务
- 错误处理:初始化失败不影响应用启动
- 确保存储目录准备就绪
4.4.4 个人中心集成
_buildMenuTile(
icon: Icons.history,
title: '浏览历史',
subtitle: '查看浏览过的游戏',
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const BrowseHistoryPage(),
),
);
},
)
- 导航跳转:点击后导航到浏览历史页面
- 用户体验:清晰的入口和说明
五、技术亮点
5.1 自动去重机制
- 去重策略:相同游戏ID + 相同类型视为重复
- 更新方式:移除旧记录,插入新记录到开头
- 优势:避免重复,保持最新记录在前
5.2 分类管理
- 类型标识:
gameType字段区分在线/经典 - 分类查询:提供按类型查询方法
- UI 展示:Tab 切换,清晰分类
- 独立清除:支持按类型清除
5.3 持久化存储
- 文件存储:JSON 文件持久化
- 平台兼容:HarmonyOS 路径获取与回退
- 双重保障:文件存储 + 内存缓存
- 自动加载:启动时自动加载历史数据
5.4 用户体验优化
- 时间显示:友好的相对时间(“刚刚”“5分钟前”)
- 空状态:无历史时显示提示
- 加载状态:加载时显示进度指示器
- 错误处理:操作失败时显示错误提示
- 下拉刷新:支持下拉刷新历史数据
- 删除反馈:删除操作后显示成功提示
5.5 性能优化
- 数量限制:最多保存100条记录
- 内存缓存:减少文件读写
- 异步处理:不阻塞UI线程
- 按需加载:只在需要时加载数据
六、总结
6.1 实现成果
- 完整的浏览历史功能:自动记录、分类管理、持久化存储
- 良好的用户体验:清晰的UI、流畅的交互、友好的提示
- 健壮的代码:完善的错误处理、平台兼容性处理
6.2 扩展方向
- 搜索功能:在历史记录中搜索游戏
- 排序功能:按时间、标题等排序
- 统计功能:显示浏览次数、最常浏览的游戏
- 同步功能:云端同步浏览历史
更多推荐



所有评论(0)