路由书签应用
欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net
适配的第三方库地址:
- go_router: https://pub.dev/packages/go_router
- shared_preferences: https://pub.dev/packages/shared_preferences
- quick_actions: https://pub.dev/packages/quick_actions
- animations: https://pub.dev/packages/animations
一、项目概述
运行效果图




1.1 应用简介
路由书签应用是一款专业的路由管理工具,支持保存路由书签、快速跳转、书签管理、书签同步等核心功能。应用以活力的橙色为主色调,象征效率与便捷。涵盖书签列表、访问历史、分类浏览、设置四大模块,用户可以快速保存常用路由、一键跳转目标页面、管理书签分类。
1.2 核心功能
| 功能模块 | 功能描述 | 实现方式 |
|---|---|---|
| 书签管理 | 添加、编辑、删除书签 | CRUD操作 |
| 快速跳转 | 一键跳转到目标路由 | 路由导航 |
| 访问历史 | 记录访问过的路由 | 历史记录 |
| 分类管理 | 按类别组织书签 | 分类系统 |
| 置顶功能 | 重要书签置顶显示 | 排序算法 |
| 收藏功能 | 收藏常用书签 | 收藏标记 |
| 同步功能 | 书签云端同步 | 云存储 |
| 导入导出 | 书签数据导入导出 | 文件操作 |
1.3 书签分类定义
| 序号 | 分类名称 | 图标 | 颜色 | 说明 |
|---|---|---|---|---|
| 1 | 首页 | home | 蓝色 | 首页相关路由 |
| 2 | 产品 | inventory_2 | 绿色 | 产品相关路由 |
| 3 | 用户 | person | 紫色 | 用户相关路由 |
| 4 | 设置 | settings | 橙色 | 设置相关路由 |
| 5 | 文档 | description | 青色 | 文档相关路由 |
| 6 | 其他 | more_horiz | 灰色 | 其他类型路由 |
1.4 书签属性定义
| 属性 | 类型 | 说明 |
|---|---|---|
| 名称 | String | 书签显示名称 |
| 路径 | String | 路由路径 |
| 描述 | String | 书签描述信息 |
| 分类 | Enum | 书签所属分类 |
| 访问次数 | int | 累计访问次数 |
| 是否收藏 | bool | 收藏标记 |
| 是否置顶 | bool | 置顶标记 |
| 参数 | Map | 路由参数 |
1.5 技术栈
| 技术领域 | 技术选型 | 版本要求 |
|---|---|---|
| 开发框架 | Flutter | >= 3.0.0 |
| 编程语言 | Dart | >= 2.17.0 |
| 设计规范 | Material Design 3 | - |
| 状态管理 | StatefulWidget | - |
| 数据存储 | 内存存储 | - |
| 目标平台 | 鸿蒙OS / Web | API 21+ |
1.6 项目结构
lib/
└── main_route_bookmark.dart
├── RouteBookmarkApp # 应用入口
├── BookmarkCategory # 书签分类枚举
├── RouteBookmark # 书签数据模型
├── RouteHistory # 访问历史模型
├── RouteBookmarkHomePage # 主页面(底部导航)
├── _buildBookmarksPage # 书签列表页
├── _buildHistoryPage # 访问历史页
├── _buildCategoriesPage # 分类浏览页
├── _buildSettingsPage # 设置页
└── _AddBookmarkDialog # 添加书签对话框
二、系统架构
2.1 整体架构图
Data Layer
Business Layer
Presentation Layer
主页面
RouteBookmarkHomePage
书签列表页
访问历史页
分类浏览页
设置页
书签卡片
搜索筛选
置顶区域
历史列表
统计概览
分类网格
书签设置
同步设置
数据管理
书签管理器
BookmarkManager
历史管理器
HistoryManager
跳转控制器
JumpController
同步管理器
SyncManager
RouteBookmark
书签数据
RouteHistory
历史数据
BookmarkCategory
分类数据
2.2 路由跳转流程
点击书签
播放跳转动画
更新访问记录
增加访问次数
添加到历史
执行路由跳转
显示跳转提示
2.3 书签排序逻辑
是
否
获取书签列表
是否置顶?
置顶区域
常规区域
按访问次数排序
返回排序列表
三、核心功能实现
3.1 书签数据模型
dart
class RouteBookmark {
final String id; // 唯一标识
final String name; // 书签名称
final String path; // 路由路径
final String description; // 描述信息
final BookmarkCategory category; // 分类
final DateTime createdAt; // 创建时间
final DateTime? lastAccessed; // 最后访问时间
final int accessCount; // 访问次数
final bool isFavorite; // 是否收藏
final bool isPinned; // 是否置顶
final Map<String, dynamic>? params; // 路由参数
}
3.2 跳转功能实现
dart
void _jumpToRoute(RouteBookmark bookmark) {
_jumpAnimationController.forward().then((_) {
_jumpAnimationController.reset();
setState(() {
// 更新访问记录
final index = _bookmarks.indexWhere((b) => b.id == bookmark.id);
if (index != -1) {
_bookmarks[index] = bookmark.copyWith(
lastAccessed: DateTime.now(),
accessCount: bookmark.accessCount + 1,
);
}
// 添加到历史
_history.insert(0, RouteHistory(
path: bookmark.path,
name: bookmark.name,
accessedAt: DateTime.now(),
));
});
// 显示跳转提示
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('跳转到: ${bookmark.path}')),
);
});
}
3.3 书签排序算法
dart
List<RouteBookmark> get _filteredBookmarks {
return _bookmarks.where((bookmark) {
// 搜索过滤
if (_searchQuery.isNotEmpty &&
!bookmark.name.toLowerCase().contains(_searchQuery.toLowerCase()) &&
!bookmark.path.toLowerCase().contains(_searchQuery.toLowerCase())) {
return false;
}
// 分类过滤
if (_filterCategory != null && bookmark.category != _filterCategory) {
return false;
}
return true;
}).toList()
..sort((a, b) {
// 置顶优先
if (a.isPinned && !b.isPinned) return -1;
if (!a.isPinned && b.isPinned) return 1;
// 按访问次数排序
return b.accessCount.compareTo(a.accessCount);
});
}
3.4 历史记录管理
dart
class RouteHistory {
final String path; // 路由路径
final String name; // 路由名称
final DateTime accessedAt; // 访问时间
}
// 时间格式化
String _formatTime(DateTime time) {
final now = DateTime.now();
final diff = now.difference(time);
if (diff.inMinutes < 60) {
return '${diff.inMinutes}分钟前';
} else if (diff.inHours < 24) {
return '${diff.inHours}小时前';
} else if (diff.inDays < 7) {
return '${diff.inDays}天前';
} else {
return '${time.month}/${time.day}';
}
}
四、界面设计
4.1 主界面布局
┌─────────────────────────────────────────────────────────────┐
│ 📑 路由书签 │
│ 共 8 个书签 │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────────────┐│
│ │ 🔍 搜索书签... ││
│ └─────────────────────────────────────────────────────────┘│
│ │
│ 📌 置顶书签 │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ 👤 用户中心 ⭐ 📌 ││
│ │ /user/profile ││
│ │ 用户个人信息页面 访问25次 ││
│ └─────────────────────────────────────────────────────────┘│
│ │
│ 全部书签 │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ 📦 产品列表 ⭐ ││
│ │ /product/list ││
│ │ 所有产品列表页面 访问18次 ││
│ └─────────────────────────────────────────────────────────┘│
│ │
│ [+ 添加书签] │
├─────────────────────────────────────────────────────────────┤
│ [书签] [历史] [分类] [设置] │
└─────────────────────────────────────────────────────────────┘
4.2 分类浏览界面
┌─────────────────────────────────────────────────────────────┐
│ 分类 │
├─────────────────────────────────────────────────────────────┤
│ ┌──────────────┐ ┌──────────────┐ │
│ │ 🏠 │ │ 📦 │ │
│ │ 首页 │ │ 产品 │ │
│ │ 2 个书签 │ │ 2 个书签 │ │
│ └──────────────┘ └──────────────┘ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ 👤 │ │ ⚙️ │ │
│ │ 用户 │ │ 设置 │ │
│ │ 2 个书签 │ │ 1 个书签 │ │
│ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
4.3 页面导航结构
底部导航
书签页
历史页
分类页
设置页
书签列表
搜索筛选
添加书签
历史列表
统计概览
分类网格
分类筛选
书签设置
同步设置
数据管理
五、交互设计
5.1 书签操作流程
编辑
删除
收藏
置顶
点击书签
执行跳转
更新访问次数
添加到历史
显示跳转提示
长按书签
选择操作
打开编辑对话框
确认删除
切换收藏状态
切换置顶状态
5.2 手势操作
| 操作方式 | 触发条件 | 响应行为 |
|---|---|---|
| 点击 | 点击书签卡片 | 跳转到目标路由 |
| 长按 | 长按卡片 | 显示操作菜单 |
| 滑动 | 左滑历史项 | 删除历史记录 |
5.3 快捷操作
| 快捷方式 | 功能描述 |
|---|---|
| 添加书签 | 创建新书签 |
| 筛选 | 按分类筛选 |
| 搜索 | 搜索书签名称/路径 |
| 清除历史 | 清空访问历史 |
六、数据模型设计
6.1 实体关系图
belongs_to
references
ROUTE_BOOKMARK
string
id
PK
string
name
string
path
string
description
string
category
datetime
createdAt
datetime
lastAccessed
int
accessCount
boolean
isFavorite
boolean
isPinned
json
params
ROUTE_HISTORY
string
path
FK
string
name
datetime
accessedAt
BOOKMARK_CATEGORY
string
code
PK
string
label
string
icon
string
color
6.2 JSON数据格式
json
{
"id": "1",
"name": "用户中心",
"path": "/user/profile",
"description": "用户个人信息页面",
"category": "user",
"createdAt": "2024-01-15T00:00:00Z",
"lastAccessed": "2024-01-20T10:30:00Z",
"accessCount": 25,
"isFavorite": true,
"isPinned": true,
"params": null
}
七、性能优化
7.1 列表优化
| 优化项 | 实现方式 | 效果 |
|---|---|---|
| 虚拟列表 | SliverList | 大数据量流畅 |
| 懒加载 | 按需构建 | 内存优化 |
| 状态缓存 | IndexedStack | 页面状态保持 |
7.2 搜索优化
dart
// 使用 where 过滤而非创建新列表
List<RouteBookmark> get _filteredBookmarks {
return _bookmarks.where((bookmark) {
// 搜索条件
}).toList();
}
八、鸿蒙适配说明
8.1 适配要点
| 适配项 | 说明 | 状态 |
|---|---|---|
| 屏幕适配 | 支持不同屏幕尺寸 | ✅ |
| 触摸交互 | 支持触摸手势操作 | ✅ |
| 路由跳转 | 适配鸿蒙路由系统 | ⏳ |
| 本地存储 | 数据持久化 | ⏳ |
| 云同步 | 书签同步功能 | ⏳ |
8.2 第三方库适配状态
| 库名 | 功能 | 鸿蒙适配状态 |
|---|---|---|
| go_router | 路由跳转 | 需适配 |
| shared_preferences | 数据存储 | 已适配 |
| quick_actions | 快捷方式 | 需适配 |
| animations | 动画效果 | 已适配 |
九、使用说明
9.1 创建书签流程
点击添加
输入名称
输入路径
选择分类
填写描述
保存书签
9.2 书签管理说明
| 操作 | 方法 | 说明 |
|---|---|---|
| 添加书签 | 点击+按钮 | 填写书签信息 |
| 编辑书签 | 点击菜单→编辑 | 修改书签信息 |
| 删除书签 | 点击菜单→删除 | 确认后删除 |
| 收藏书签 | 点击菜单→收藏 | 添加收藏标记 |
| 置顶书签 | 点击菜单→置顶 | 置顶显示 |
9.3 同步功能说明
| 功能 | 说明 |
|---|---|
| 上传书签 | 将本地书签上传到云端 |
| 下载书签 | 从云端下载书签到本地 |
| 自动同步 | 定期自动同步书签数据 |
十、扩展功能
10.1 未来规划
| 功能 | 优先级 | 预计版本 |
|---|---|---|
| 书签分组 | 高 | v2.0 |
| 书签标签 | 高 | v2.0 |
| 快捷跳转 | 中 | v2.5 |
| 书签分享 | 中 | v2.5 |
| 书签导入 | 低 | v3.0 |
| 书签模板 | 低 | v3.0 |
10.2 自定义扩展点
dart
// 自定义书签分类
abstract class CustomBookmarkCategory {
String get label;
IconData get icon;
Color get color;
}
// 注册自定义分类
void registerCategory(CustomBookmarkCategory category) {
// 注册逻辑
}
十一、常见问题
11.1 FAQ
| 问题 | 解决方案 |
|---|---|
| 书签无法跳转 | 检查路由路径是否正确 |
| 书签丢失 | 检查是否清除了数据 |
| 同步失败 | 检查网络连接 |
| 书签重复 | 使用去重功能 |
11.2 错误代码
| 错误码 | 描述 | 解决方案 |
|---|---|---|
| E001 | 路径格式无效 | 使用正确的路径格式 |
| E002 | 书签名称为空 | 输入书签名称 |
| E003 | 分类无效 | 选择有效分类 |
| E004 | 同步失败 | 检查网络连接 |