


在 Flutter 应用开发中,路由(Routing)与导航(Navigation) 是构建多页面应用的核心机制。无论是简单的页面跳转,还是复杂的嵌套路由管理,掌握路由系统对提升用户体验和代码可维护性至关重要。
本文将带你从基础到进阶,全面掌握 Flutter 的路由与导航。
Flutter 使用 Navigator widget 来管理页面栈,通过 push 和 pop 操作实现页面切换。
适用于简单场景,直接传递 Widget 实例。
// 跳转到新页面
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SecondScreen()),
);
// 返回上一页
Navigator.pop(context);✅ 优点:简单直接 ❌ 缺点:难以维护,无法统一管理


通过字符串名称注册路由,便于集中管理和传参。
MaterialApp 中定义路由表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(),
},
);
}
}// 跳转
Navigator.pushNamed(context, '/second');
// 带参数跳转(稍后详述)
Navigator.pushNamed(context, '/profile', arguments: {'userId': 123});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')),
);
}
}✅ 优点:结构清晰、易于测试、支持深链接 ✅ 推荐用于中大型项目


arguments(如上所示)适用于简单数据(如 int、String、Map)。
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可实现类型安全的路由。
默认是水平滑动,但你可以自定义:
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:
// 在第一个页面
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SelectionScreen()),
);
if (result != null) {
print('用户选择了: $result');
}
// 在第二个页面
Navigator.pop(context, '选项A'); // 返回数据在 MaterialApp 中设置 onUnknownRoute:
MaterialApp(
onUnknownRoute: (settings) {
return MaterialPageRoute(
builder: (context) => const NotFoundScreen(),
);
},
);对于包含底部导航栏(BottomNavigationBar)或多级 Tab 的应用,建议使用 嵌套 Navigator 或 go_router(官方推荐)。
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。
dependencies:
go_router: ^14.0.0final 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 替代):
PopScope(
canPop: false,
child: Scaffold(...),
)Q:如何清空路由栈并跳转?
A:使用 pushNamedAndRemoveUntil:
Navigator.pushNamedAndRemoveUntil(
context,
'/login',
(route) => false, // 移除所有路由
);掌握 Flutter 路由与导航,是构建流畅用户体验的关键一步。从基础的 Navigator.push 到现代化的 go_router,选择适合你项目复杂度的方案,能让代码更清晰、维护更轻松。
📌 提示:随着 Flutter 3.0+ 的演进,官方越来越推荐使用声明式路由(如
go_router),尤其在跨平台(含 Web)项目中。
希望本教程对你有所帮助!如有疑问,欢迎留言讨论。