
-
个人首页: VON
-
鸿蒙系列专栏: 鸿蒙开发小型案例总结
-
综合案例 :鸿蒙综合案例开发
-
鸿蒙6.0:从0开始的开源鸿蒙6.0.0
-
鸿蒙5.0:鸿蒙5.0零基础入门到项目实战
-
Electron适配开源鸿蒙专栏:Electron for OpenHarmony
-
本文章所属专栏:Flutter for OpenHarmony
Flutter for OpenHarmony前置知识
- [Flutter 路由与导航完整教程(2025 年版)](#Flutter 路由与导航完整教程(2025 年版))
-
- 一、什么是路由与导航?
- [二、基础导航:使用命名路由 vs 非命名路由](#二、基础导航:使用命名路由 vs 非命名路由)
-
- [1. 非命名路由(匿名路由)](#1. 非命名路由(匿名路由))
- [2. 命名路由(推荐)](#2. 命名路由(推荐))
-
- [步骤 1:在 `MaterialApp` 中定义路由表](#步骤 1:在
MaterialApp中定义路由表) - [步骤 2:使用命名路由跳转](#步骤 2:使用命名路由跳转)
- [步骤 3:接收参数(在目标页面)](#步骤 3:接收参数(在目标页面))
- [步骤 1:在 `MaterialApp` 中定义路由表](#步骤 1:在
- 三、传递与接收参数的高级方式
-
- [方法 1:使用 `arguments`(如上所示)](#方法 1:使用
arguments(如上所示)) - [方法 2:自定义参数类(更安全)](#方法 2:自定义参数类(更安全))
- [方法 1:使用 `arguments`(如上所示)](#方法 1:使用
- 四、自定义路由动画
- 五、返回值(从页面获取数据)
- [六、处理未知路由(404 页面)](#六、处理未知路由(404 页面))
- [七、嵌套路由(适用于复杂 App)](#七、嵌套路由(适用于复杂 App))
- [八、推荐:使用 `go_router`(官方现代化方案)](#八、推荐:使用
go_router(官方现代化方案)) - 九、最佳实践总结
- 十、常见问题
- 结语

Flutter 路由与导航完整教程(2025 年版)
在 Flutter 应用开发中,路由(Routing)与导航(Navigation) 是构建多页面应用的核心机制。无论是简单的页面跳转,还是复杂的嵌套路由管理,掌握路由系统对提升用户体验和代码可维护性至关重要。
本文将带你从基础到进阶,全面掌握 Flutter 的路由与导航。
一、什么是路由与导航?
- 路由(Route):代表应用中的一个"页面"或"屏幕",可以理解为 URL 对应的视图。
- 导航(Navigator):负责管理这些路由的堆栈(stack),控制页面的进入与退出。
Flutter 使用 Navigator widget 来管理页面栈,通过 push 和 pop 操作实现页面切换。
二、基础导航:使用命名路由 vs 非命名路由
1. 非命名路由(匿名路由)
适用于简单场景,直接传递 Widget 实例。
dart
// 跳转到新页面
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SecondScreen()),
);
// 返回上一页
Navigator.pop(context);
✅ 优点:简单直接
❌ 缺点:难以维护,无法统一管理


2. 命名路由(推荐)
通过字符串名称注册路由,便于集中管理和传参。
步骤 1:在 MaterialApp 中定义路由表
dart
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter 路由示例',
initialRoute: '/',
routes: {
'/': (context) => const HomeScreen(),
'/second': (context) => const SecondScreen(),
'/profile': (context) => const ProfileScreen(),
},
);
}
}
步骤 2:使用命名路由跳转
dart
// 跳转
Navigator.pushNamed(context, '/second');
// 带参数跳转(稍后详述)
Navigator.pushNamed(context, '/profile', arguments: {'userId': 123});
步骤 3:接收参数(在目标页面)
dart
class ProfileScreen extends StatelessWidget {
const ProfileScreen({super.key});
@override
Widget build(BuildContext context) {
final args = ModalRoute.of(context)?.settings.arguments as Map?;
final userId = args?['userId'] ?? 0;
return Scaffold(
appBar: AppBar(title: Text('用户 $userId')),
body: Center(child: Text('欢迎用户 $userId')),
);
}
}
✅ 优点:结构清晰、易于测试、支持深链接
✅ 推荐用于中大型项目


三、传递与接收参数的高级方式
方法 1:使用 arguments(如上所示)
适用于简单数据(如 int、String、Map)。
方法 2:自定义参数类(更安全)
dart
class ProfileArguments {
final int userId;
final String name;
ProfileArguments(this.userId, this.name);
}
// 跳转时
Navigator.pushNamed(
context,
'/profile',
arguments: ProfileArguments(42, '张三'),
);
// 接收时
final args = ModalRoute.of(context)?.settings.arguments as ProfileArguments?;
💡 提示:配合
onGenerateRoute可实现类型安全的路由。
四、自定义路由动画
默认是水平滑动,但你可以自定义:
dart
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => const CustomScreen(),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
return FadeTransition(opacity: animation, child: child);
},
),
);

常用过渡效果:
FadeTransition:淡入淡出ScaleTransition:缩放SlideTransition:滑动(可自定义方向)
五、返回值(从页面获取数据)
类似 Android 的 startActivityForResult:
dart
// 在第一个页面
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SelectionScreen()),
);
if (result != null) {
print('用户选择了: $result');
}
// 在第二个页面
Navigator.pop(context, '选项A'); // 返回数据
六、处理未知路由(404 页面)
在 MaterialApp 中设置 onUnknownRoute:
dart
MaterialApp(
onUnknownRoute: (settings) {
return MaterialPageRoute(
builder: (context) => const NotFoundScreen(),
);
},
);
七、嵌套路由(适用于复杂 App)
对于包含底部导航栏(BottomNavigationBar)或多级 Tab 的应用,建议使用 嵌套 Navigator 或 go_router(官方推荐)。
简单嵌套示例:
dart
class HomeTab extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Navigator(
onGenerateRoute: (settings) {
if (settings.name == '/') {
return MaterialPageRoute(builder: (_) => HomePage());
} else if (settings.name == '/detail') {
return MaterialPageRoute(builder: (_) => DetailPage());
}
return null;
},
);
}
}
⚠️ 注意:嵌套 Navigator 会创建独立的路由栈,需谨慎管理。
八、推荐:使用 go_router(官方现代化方案)
对于复杂应用(尤其是需要深度链接、Web 支持、状态管理集成),强烈推荐使用 go_router。
安装
yaml
dependencies:
go_router: ^14.0.0
基本用法
dart
final GoRouter _router = GoRouter(
routes: [
GoRoute(
path: '/',
builder: (context, state) => const HomeScreen(),
),
GoRoute(
path: '/profile/:id',
builder: (context, state) {
final id = state.params['id']!;
return ProfileScreen(userId: int.parse(id));
},
),
],
);
MaterialApp.router(
routerConfig: _router,
);
✅ 支持路径参数(
:id)、查询参数、重定向、异步守卫等✅ 与 Web URL 同步,天然支持深链接
九、最佳实践总结
| 场景 | 推荐方案 |
|---|---|
| 简单 App(2~3 页) | 命名路由 + routes |
| 需要传参/返回值 | arguments + 自定义参数类 |
| 复杂 App / Web 支持 | go_router |
| 自定义过渡动画 | PageRouteBuilder |
| 错误处理 | onUnknownRoute |
十、常见问题
Q:如何禁止返回上一页?
A:使用 WillPopScope(注意:在较新版本中已被 PopScope 替代):
dart
PopScope(
canPop: false,
child: Scaffold(...),
)
Q:如何清空路由栈并跳转?
A:使用 pushNamedAndRemoveUntil:
dart
Navigator.pushNamedAndRemoveUntil(
context,
'/login',
(route) => false, // 移除所有路由
);
结语
掌握 Flutter 路由与导航,是构建流畅用户体验的关键一步。从基础的 Navigator.push 到现代化的 go_router,选择适合你项目复杂度的方案,能让代码更清晰、维护更轻松。
📌 提示 :随着 Flutter 3.0+ 的演进,官方越来越推荐使用声明式路由(如
go_router),尤其在跨平台(含 Web)项目中。
希望本教程对你有所帮助!如有疑问,欢迎留言讨论。