在这里插入图片描述

在这里插入图片描述

Flutter 路由与导航完整教程(2025 年版)

在 Flutter 应用开发中,路由(Routing)与导航(Navigation) 是构建多页面应用的核心机制。无论是简单的页面跳转,还是复杂的嵌套路由管理,掌握路由系统对提升用户体验和代码可维护性至关重要。

本文将带你从基础到进阶,全面掌握 Flutter 的路由与导航。


一、什么是路由与导航?

  • 路由(Route):代表应用中的一个“页面”或“屏幕”,可以理解为 URL 对应的视图。
  • 导航(Navigator):负责管理这些路由的堆栈(stack),控制页面的进入与退出。

Flutter 使用 Navigator widget 来管理页面栈,通过 pushpop 操作实现页面切换。


二、基础导航:使用命名路由 vs 非命名路由

1. 非命名路由(匿名路由)

适用于简单场景,直接传递 Widget 实例。

// 跳转到新页面
Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => const SecondScreen()),
);

// 返回上一页
Navigator.pop(context);

✅ 优点:简单直接
❌ 缺点:难以维护,无法统一管理


在这里插入图片描述
在这里插入图片描述

2. 命名路由(推荐)

通过字符串名称注册路由,便于集中管理和传参。

步骤 1:在 MaterialApp 中定义路由表
void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter 路由示例',
      initialRoute: '/',
      routes: {
        '/': (context) => const HomeScreen(),
        '/second': (context) => const SecondScreen(),
        '/profile': (context) => const ProfileScreen(),
      },
    );
  }
}
步骤 2:使用命名路由跳转
// 跳转
Navigator.pushNamed(context, '/second');

// 带参数跳转(稍后详述)
Navigator.pushNamed(context, '/profile', arguments: {'userId': 123});
步骤 3:接收参数(在目标页面)
class ProfileScreen extends StatelessWidget {
  const ProfileScreen({super.key});

  
  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:自定义参数类(更安全)

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'); // 返回数据

六、处理未知路由(404 页面)

MaterialApp 中设置 onUnknownRoute

MaterialApp(
  onUnknownRoute: (settings) {
    return MaterialPageRoute(
      builder: (context) => const NotFoundScreen(),
    );
  },
);

七、嵌套路由(适用于复杂 App)

对于包含底部导航栏(BottomNavigationBar)或多级 Tab 的应用,建议使用 嵌套 Navigatorgo_router(官方推荐)。

简单嵌套示例:

class HomeTab extends StatelessWidget {
  
  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.0

基本用法

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 替代):

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)项目中。

希望本教程对你有所帮助!如有疑问,欢迎留言讨论。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新

更多推荐