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



1.1 应用简介
路由导航应用是一款演示Flutter路由管理功能的教学应用,展示了页面导航、路由守卫、深链接、导航历史等核心路由概念。应用采用现代化的设计风格,以紫色为主色调,提供直观的路由演示界面,帮助开发者理解和掌握Flutter路由系统的使用方法。
应用涵盖首页、消息、搜索、收藏、个人中心五大模块,通过实际案例演示了声明式路由、命令式导航、路由参数传递、路由拦截等高级功能,是学习Flutter路由开发的理想参考。
1.2 核心功能
| 功能模块 | 功能描述 | 实现方式 |
|---|---|---|
| 页面导航 | 页面间跳转与返回 | Navigator |
| 路由守卫 | 登录状态检查与拦截 | 状态管理 |
| 深链接 | 外部链接直接跳转 | 路由解析 |
| 导航历史 | 记录访问路径 | 历史管理器 |
| 转场动画 | 页面切换动画效果 | PageRouteBuilder |
| 路由参数 | 页面间数据传递 | 构造函数参数 |
| 底部导航 | Tab页面切换 | NavigationBar |
| 登录认证 | 用户身份验证 | AuthState |
1.3 路由类型定义
| 序号 | 路由类型 | Emoji | 描述 | 示例路径 |
|---|---|---|---|---|
| 1 | 首页 | 🏠 | 应用主页面 | / |
| 2 | 商品列表 | 🛍️ | 浏览商品 | /products |
| 3 | 商品详情 | 📦 | 商品信息 | /products/:id |
| 4 | 订单列表 | 📋 | 订单管理 | /orders |
| 5 | 订单详情 | 📄 | 订单信息 | /orders/:id |
| 6 | 个人中心 | 👤 | 用户信息 | /profile |
| 7 | 消息中心 | 💬 | 消息通知 | /messages |
| 8 | 收藏夹 | ❤️ | 收藏商品 | /favorites |
| 9 | 搜索 | 🔍 | 搜索功能 | /search |
| 10 | 设置 | ⚙️ | 应用设置 | /settings |
1.4 路由权限定义
| 序号 | 权限级别 | Emoji | 描述 | 需要登录 |
|---|---|---|---|---|
| 1 | 公开 | 🌐 | 所有人可访问 | 否 |
| 2 | 登录 | 🔐 | 需要登录后访问 | 是 |
1.5 技术栈
| 技术领域 | 技术选型 | 版本要求 |
|---|---|---|
| 开发框架 | Flutter | >= 3.0.0 |
| 编程语言 | Dart | >= 2.17.0 |
| 设计规范 | Material Design 3 | - |
| 状态管理 | ChangeNotifier | - |
| 数据存储 | SharedPreferences | >= 2.0.0 |
| 动画效果 | PageRouteBuilder | - |
| 生物认证 | local_auth | >= 2.0.0 |
| 目标平台 | 鸿蒙OS / Web | API 21+ |
1.6 项目结构
lib/
└── main_router_navigation.dart
├── AppRoute # 路由配置模型
├── RouterNavigationApp # 应用入口
├── AuthState # 认证状态管理
├── NavigationHistory # 导航历史管理
├── AppRoutes # 路由配置列表
├── MainShell # 主壳组件(底部导航)
├── HomePage # 首页
├── ProfilePage # 个人中心页
├── SettingsPage # 设置页
├── MessagesPage # 消息页
├── ProductsPage # 商品列表页
├── ProductDetailPage # 商品详情页
├── OrdersPage # 订单列表页
├── OrderDetailPage # 订单详情页
├── FavoritesPage # 收藏夹页
├── SearchPage # 搜索页
└── LoginPage # 登录页
二、系统架构
2.1 整体架构图
Data Layer
Business Layer
Presentation Layer
主壳组件
MainShell
首页
消息页
搜索页
收藏页
个人中心
路由列表
快捷入口
导航历史
深链接演示
用户信息
功能菜单
认证状态
AuthState
导航历史
NavigationHistory
路由配置
AppRoutes
AppRoute
路由模型
SharedPreferences
数据存储
2.2 类图设计
contains
uses
uses
RouterNavigationApp
+Widget build()
AppRoute
+String path
+String name
+String description
+IconData icon
+bool requiresAuth
AuthState
-bool _isAuthenticated
-String _userName
-String _userEmail
+bool isAuthenticated
+String userName
+String userEmail
+login()
+logout()
NavigationHistory
-List<String> _history
-int _maxHistory
+List<String> history
+add()
+clear()
AppRoutes
+List<AppRoute> routes
MainShell
-int _currentIndex
-List<Widget> _pages
+Widget build()
2.3 页面导航流程
首页
消息
搜索
收藏
我的
是
是
否
是
否
否
应用启动
MainShell
底部导航
HomePage
MessagesPage
SearchPage
FavoritesPage
ProfilePage
点击路由
需要登录?
已登录?
跳转目标页面
显示登录对话框
LoginPage
登录成功?
记录导航历史
播放转场动画
显示目标页面
2.4 路由守卫流程
目标页面 登录页 认证状态 路由守卫 首页 用户 目标页面 登录页 认证状态 路由守卫 首页 用户 alt [已登录] [未登录] 点击需要登录的路由 检查路由权限 获取登录状态 已登录 允许跳转 显示页面 未登录 拦截跳转 显示登录对话框 确认登录 执行登录 登录成功 跳转目标页面 显示页面
三、核心模块设计
3.1 数据模型设计
3.1.1 路由配置模型 (AppRoute)
dart
class AppRoute {
final String path;
final String name;
final String description;
final IconData icon;
final bool requiresAuth;
const AppRoute({
required this.path,
required this.name,
required this.description,
required this.icon,
this.requiresAuth = false,
});
}
3.1.2 认证状态管理 (AuthState)
dart
class AuthState extends ChangeNotifier {
static final AuthState instance = AuthState._();
AuthState._();
bool _isAuthenticated = false;
String _userName = '';
String _userEmail = '';
bool get isAuthenticated => _isAuthenticated;
String get userName => _userName;
String get userEmail => _userEmail;
void login(String name, String email) {
_isAuthenticated = true;
_userName = name;
_userEmail = email;
notifyListeners();
}
void logout() {
_isAuthenticated = false;
_userName = '';
_userEmail = '';
notifyListeners();
}
}
3.1.3 导航历史管理 (NavigationHistory)
dart
class NavigationHistory {
static final NavigationHistory instance = NavigationHistory._();
NavigationHistory._();
final List<String> _history = [];
final int _maxHistory = 50;
List<String> get history => List.unmodifiable(_history);
void add(String path) {
if (_history.isNotEmpty && _history.last == path) return;
_history.add(path);
if (_history.length > _maxHistory) {
_history.removeAt(0);
}
}
void clear() {
_history.clear();
}
}
3.1.4 路由访问分布
30% 25% 20% 10% 8% 7% 路由访问分布示例 首页 商品列表 商品详情 个人中心 消息中心 其他
3.2 页面结构设计
3.2.1 主壳组件布局
MainShell
AnimatedSwitcher
NavigationBar
HomePage
MessagesPage
SearchPage
FavoritesPage
ProfilePage
首页 Tab
消息 Tab
搜索 Tab
收藏 Tab
我的 Tab
3.2.2 首页结构
HomePage
SliverAppBar
快捷入口
路由列表
导航历史
深链接演示
商品
订单
收藏
消息
路由卡片
权限标识
跳转按钮
3.2.3 路由守卫结构
否
是
是
否
取消
登录
成功
失败
路由请求
检查路由配置
requiresAuth?
直接跳转
isAuthenticated?
显示登录对话框
用户选择
返回原页面
跳转登录页
登录结果
3.3 路由导航逻辑
简单路径
带参数路径
是
否
是
否
是
否
发起导航请求
解析目标路径
路径类型
匹配路由配置
提取路径参数
需要认证?
已认证?
创建目标页面
显示认证界面
记录导航历史
创建路由动画
执行页面跳转
认证成功?
取消导航
3.4 深链接处理逻辑
否
是
是
否
是
否
是
否
接收深链接
解析URL
提取路径和参数
路径有效?
显示错误页面
需要认证?
已认证?
导航到目标页面
保存目标路径
跳转登录页
登录成功?
恢复目标路径
返回首页
更新导航历史
显示目标页面
四、UI设计规范
4.1 配色方案
应用以紫色为主色调,象征创新与探索:
| 颜色类型 | 色值 | 用途 |
|---|---|---|
| 主色 | #673AB7 (Deep Purple) | 导航、主题元素 |
| 辅助色 | #9575CD | 选中状态 |
| 第三色 | #D1C4E9 | 悬停状态 |
| 背景色 | #FAFAFA | 页面背景 |
| 卡片背景 | #FFFFFF | 信息卡片 |
| 成功色 | #4CAF50 | 登录成功 |
| 警告色 | #FF9800 | 需要登录 |
| 错误色 | #F44336 | 访问拒绝 |
4.2 路由状态配色
| 状态 | 色值 | 视觉效果 |
|---|---|---|
| 公开路由 | #4CAF50 | 绿色 |
| 需登录路由 | #FF9800 | 橙色 |
| 当前页面 | #673AB7 | 紫色 |
4.3 字体规范
| 元素 | 字号 | 字重 | 颜色 |
|---|---|---|---|
| 页面标题 | 24px | Bold | 主色 |
| 路由名称 | 16px | Bold | #000000 |
| 路由描述 | 14px | Regular | #666666 |
| 路径显示 | 12px | Regular | #999999 |
| 标签文字 | 10px | Regular | 分类颜色 |
4.4 组件规范
4.4.1 路由卡片
┌─────────────────────────────────────┐
│ 🏠 首页 ▶ │
│ 应用主页面 │
│ │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ 🔐 个人中心 [需登录] ▶ │
│ 查看和管理个人信息 │
│ │
└─────────────────────────────────────┘
4.4.2 快捷入口
┌─────────────────────────────────────┐
│ 快捷入口 │
│ │
│ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
│ │ 🛍️ │ │ 📋 │ │ ❤️ │ │ 💬 │
│ │ 商品 │ │ 订单 │ │ 收藏 │ │ 消息 │
│ └────────┘ └────────┘ └────────┘ └────────┘
└─────────────────────────────────────┘
4.4.3 导航历史
┌─────────────────────────────────────┐
│ 导航历史 清除 │
│ │
│ [/products/1] [/orders] [/profile] │
│ [/settings] [/messages] │
│ │
└─────────────────────────────────────┘
4.4.4 深链接按钮
┌─────────────────────────────────────┐
│ 深链接演示 │
│ │
│ 深链接可以从外部应用直接跳转到指定 │
│ 页面,常用于推送通知、分享链接等。 │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ │ 🔗 商品#1 │ │ 🔗 订单#1 │ │ 🔗 用户页 │
│ └──────────┘ └──────────┘ └──────────┘
└─────────────────────────────────────┘
五、核心功能实现
5.1 路由导航实现
dart
void _navigateToRoute(BuildContext context, String path) {
final route = AppRoutes.routes
.where((r) => path.startsWith(r.path))
.firstOrNull;
final requiresAuth = route?.requiresAuth ?? false;
if (requiresAuth && !AuthState.instance.isAuthenticated) {
_showLoginDialog(context, path);
return;
}
NavigationHistory.instance.add(path);
Widget targetPage;
if (path.startsWith('/products/')) {
final id = path.split('/').last;
targetPage = ProductDetailPage(productId: id);
} else if (path.startsWith('/orders/')) {
final id = path.split('/').last;
targetPage = OrderDetailPage(orderId: id);
} else {
// 根据路径匹配对应页面
switch (path) {
case '/profile':
targetPage = const ProfilePage();
break;
// ... 其他路由
}
}
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => targetPage,
transitionsBuilder: (context, animation, secondaryAnimation, child) {
const begin = Offset(1.0, 0.0);
const end = Offset.zero;
const curve = Curves.easeInOutCubic;
var tween = Tween(begin: begin, end: end)
.chain(CurveTween(curve: curve));
return SlideTransition(
position: animation.drive(tween),
child: child,
);
},
),
);
}
5.2 路由守卫实现
dart
void _showLoginDialog(BuildContext context, String fromPath) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('需要登录'),
content: const Text('此功能需要登录后才能访问,是否立即登录?'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('取消'),
),
ElevatedButton(
onPressed: () {
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => LoginPage(fromPath: fromPath),
),
);
},
child: const Text('登录'),
),
],
),
);
}
5.3 转场动画实现
dart
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => targetPage,
transitionsBuilder: (context, animation, secondaryAnimation, child) {
const begin = Offset(1.0, 0.0);
const end = Offset.zero;
const curve = Curves.easeInOutCubic;
var tween = Tween(begin: begin, end: end)
.chain(CurveTween(curve: curve));
return SlideTransition(
position: animation.drive(tween),
child: child,
);
},
transitionDuration: const Duration(milliseconds: 300),
),
);
5.4 深链接模拟实现
dart
Widget _buildDeepLinkButton(BuildContext context, String label, String path) {
return ElevatedButton.icon(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('模拟深链接: $path'),
action: SnackBarAction(
label: '跳转',
onPressed: () => _navigateToRoute(context, path),
),
),
);
},
icon: const Icon(Icons.link, size: 18),
label: Text(label),
);
}
5.5 底部导航实现
dart
class MainShell extends StatefulWidget {
const MainShell({super.key});
@override
State<MainShell> createState() => _MainShellState();
}
class _MainShellState extends State<MainShell> {
int _currentIndex = 0;
final List<Widget> _pages = [
const HomePage(),
const MessagesPage(),
const SearchPage(),
const FavoritesPage(),
const ProfilePage(),
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: AnimatedSwitcher(
duration: const Duration(milliseconds: 300),
child: _pages[_currentIndex],
),
bottomNavigationBar: NavigationBar(
selectedIndex: _currentIndex,
onDestinationSelected: (index) {
setState(() {
_currentIndex = index;
});
},
destinations: const [
NavigationDestination(
icon: Icon(Icons.home_outlined),
selectedIcon: Icon(Icons.home),
label: '首页',
),
// ... 其他导航项
],
),
);
}
}
六、交互设计
6.1 页面跳转流程
目标页面 路由守卫 当前页面 用户 目标页面 路由守卫 当前页面 用户 alt [无需登录] [需要登录] 点击跳转按钮 检查路由权限 允许跳转 执行跳转动画 显示新页面 需要认证 显示登录对话框 确认登录 登录后跳转 显示新页面
6.2 登录认证流程
已登录
未登录
取消
登录
成功
失败
访问需登录页面
检查登录状态
直接访问
显示登录对话框
用户选择
返回原页面
跳转登录页
输入用户名密码
点击登录按钮
验证用户信息
验证结果
更新认证状态
显示错误提示
返回目标页面
显示页面内容
6.3 深链接处理流程
路径存在
路径无效
requiresAuth=true
requiresAuth=false
isAuthenticated=true
isAuthenticated=false
认证通过
用户取消
接收深链接
解析URL
验证路径
有效路径
错误页面
检查权限
需要登录
直接跳转
已登录
登录页面
目标页面
登录成功
取消登录
七、扩展功能规划
7.1 后续版本规划
2024-01-07 2024-01-14 2024-01-21 2024-01-28 2024-02-04 2024-02-11 2024-02-18 2024-02-25 2024-03-03 2024-03-10 2024-03-17 2024-03-24 基础路由框架 路由守卫实现 转场动画效果 深链接支持 导航历史功能 路由参数传递 命名路由支持 路由分组管理 懒加载路由 V1.0 基础版本 V1.1 增强版本 V1.2 进阶版本 路由导航应用开发计划
7.2 功能扩展建议
7.2.1 命名路由支持
命名路由功能:
- 使用字符串名称标识路由
- 统一管理路由映射表
- 支持路由别名
- 简化路由调用
7.2.2 路由分组管理
分组管理功能:
- 按模块分组路由
- 支持路由中间件
- 批量添加路由
- 路由优先级管理
7.2.3 懒加载路由
懒加载功能:
- 按需加载页面代码
- 减少初始包体积
- 提升启动速度
- 优化内存占用
八、注意事项
8.1 开发注意事项
-
路由管理:保持路由配置的一致性,避免重复定义
-
状态同步:认证状态变化时及时通知相关页面更新
-
内存管理:及时清理不需要的导航历史记录
-
错误处理:处理无效路由路径,显示友好错误页面
-
性能优化:使用AnimatedSwitcher优化Tab切换性能
8.2 常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 路由跳转失败 | 路径配置错误 | 检查路由配置表 |
| 登录状态不同步 | 未使用状态管理 | 使用ChangeNotifier |
| 动画卡顿 | 动画时间过长 | 缩短动画时间 |
| 深链接无效 | URL格式错误 | 检查URL解析逻辑 |
| 历史记录过多 | 未设置上限 | 限制历史记录数量 |
8.3 使用技巧
🔗 路由导航应用技巧 🔗
路由管理
- 使用常量定义路由路径
- 统一管理路由配置
- 合理设置路由权限
- 保持路由命名规范
性能优化
- 使用AnimatedSwitcher切换页面
- 避免重复创建页面实例
- 及时清理导航历史
- 合理使用路由缓存
用户体验
- 添加页面转场动画
- 提供清晰的导航反馈
- 处理异常路由情况
- 保存用户导航状态
九、鸿蒙Flutter适配说明
9.1 适配要点
| 适配项 | 说明 | 状态 |
|---|---|---|
| 基础UI组件 | 使用Material Design 3 | ✅ 已适配 |
| 状态管理 | ChangeNotifier模式 | ✅ 已适配 |
| 数据存储 | SharedPreferences | ✅ 已适配 |
| 动画效果 | PageRouteBuilder | ✅ 已适配 |
| 生物认证 | local_auth插件 | ⚠️ 需验证 |
9.2 权限配置
在鸿蒙OS上运行需要配置以下权限:
json
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
},
{
"name": "ohos.permission.GET_NETWORK_INFO"
},
{
"name": "ohos.permission.USE_BIOMETRIC"
}
]
}
}
9.3 运行命令
bash
# 查看可用设备
flutter devices
# 运行到Web服务器
flutter run -d web-server -t lib/main_router_navigation.dart --web-port 8153
# 运行到鸿蒙设备
flutter run -d 127.0.0.1:5555 lib/main_router_navigation.dart
# 代码分析
flutter analyze lib/main_router_navigation.dart
十、总结
路由导航应用是一款功能完善的路由管理演示工具,展示了Flutter路由系统的核心功能。应用支持页面导航、路由守卫、深链接、导航历史、转场动画、路由参数传递、底部导航、登录认证八大核心功能,帮助开发者全面理解和掌握Flutter路由开发。
应用采用 Material Design 3 设计规范,以紫色为主色调,象征创新与探索。通过本应用,开发者可以学习到声明式路由、命令式导航、路由拦截、参数传递等高级路由技术,为实际项目开发提供参考。
路由导航应用------掌握Flutter路由开发