Flutter for OpenHarmony前置知识《Flutter 路由与导航完整教程》

Flutter for OpenHarmony前置知识

  • [Flutter 路由与导航完整教程(2025 年版)](#Flutter 路由与导航完整教程(2025 年版))
    • 一、什么是路由与导航?
    • [二、基础导航:使用命名路由 vs 非命名路由](#二、基础导航:使用命名路由 vs 非命名路由)
      • [1. 非命名路由(匿名路由)](#1. 非命名路由(匿名路由))
      • [2. 命名路由(推荐)](#2. 命名路由(推荐))
        • [步骤 1:在 `MaterialApp` 中定义路由表](#步骤 1:在 MaterialApp 中定义路由表)
        • [步骤 2:使用命名路由跳转](#步骤 2:使用命名路由跳转)
        • [步骤 3:接收参数(在目标页面)](#步骤 3:接收参数(在目标页面))
    • 三、传递与接收参数的高级方式
      • [方法 1:使用 `arguments`(如上所示)](#方法 1:使用 arguments(如上所示))
      • [方法 2:自定义参数类(更安全)](#方法 2:自定义参数类(更安全))
    • 四、自定义路由动画
    • 五、返回值(从页面获取数据)
    • [六、处理未知路由(404 页面)](#六、处理未知路由(404 页面))
    • [七、嵌套路由(适用于复杂 App)](#七、嵌套路由(适用于复杂 App))
    • [八、推荐:使用 `go_router`(官方现代化方案)](#八、推荐:使用 go_router(官方现代化方案))
    • 九、最佳实践总结
    • 十、常见问题
    • 结语

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

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

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


一、什么是路由与导航?

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

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


二、基础导航:使用命名路由 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 的应用,建议使用 嵌套 Navigatorgo_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)项目中。

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

相关推荐
松☆41 分钟前
Flutter + OpenHarmony 构建工业巡检 App:离线采集、多端协同与安全上报
安全·flutter
天意__1 小时前
Flutter开发,scroll_to_index适配flutter_list_view
前端·flutter
Ya-Jun1 小时前
架构设计模式:模块化设计方案
flutter
搞机械的假程序猿1 小时前
普中51单片机学习笔记-AT24C02读写
笔记·学习·51单片机
光影少年1 小时前
web3学习路线
前端·学习·前端框架·web3
克喵的水银蛇1 小时前
Flutter 状态管理:Provider 入门到实战(替代 setState)
前端·javascript·flutter
鹏多多1 小时前
flutter-使用url_launcher打开链接/应用/短信/邮件和评分跳转等
android·前端·flutter
暗然而日章1 小时前
C++基础:Stanford CS106L学习笔记 3 流
c++·笔记·学习