Flutter开发笔记:路由技术

举报
jcLee95 发表于 2023/06/26 23:35:02 2023/06/26
【摘要】 Flutter开发笔记:路由技术
Flutter
Flutter开发笔记:路由技术

- 文章信息 -
Author: Jack Lee (jcLee95)
Visit me at: https://jclee95.blog.csdn.net
Email: 291148484@163.com.
Shenzhen Chine
Address of this article:https://blog.csdn.net/qq_28550263/article/details/131376141

【介绍】:本文介绍 Flutter 路由的原理,以及 go_router 模块的用法。


目 录





移动端应用开发中,路由技术是一个非常重要的组成部分。路由技术负责管理应用中各个页面之间的跳转、导航以及参数传递等关键功能。在移动端应用中,一个高效、易于维护的路由系统对于提高开发效率和用户体验具有重要意义。


本文将对 Flutter 移动端应用开发中的路由技术进行详细讲解,内容涵盖以下几个方面:

  • Flutter 路由基础知识,包括核心概念、基本操作以及传参等;
  • 命名路由与动态路由的定义、使用以及对比;
  • go_router 模块的介绍,包括安装、配置、定义和注册路由等;
  • 使用 go_router 实现页面导航、处理深度链接、重定向等高级功能;
  • 路由守卫与路由过渡动画的实现;
  • 通过实战案例,展示如何使用 go_router 构建一个完整的移动端应用。

通过学习本文,可以掌握 Flutter 路由技术的基本原理和实践方法,为开发高质量的移动端应用奠定坚实基础。



 Flutter 中,路由技术的核心概念包括两个要素:Route  Navigator


Route 代表应用中的一个页面,它包含了页面的布局、逻辑以及生命周期等信息。在 Flutter 中,Route通常是一个继承自PageRoute的类。

PageRoute是一个抽象类,表示一个可以用于Navigator的页面。它包含了页面的构建方法、过渡动画以及页面的生命周期回调等属性。在实际开发中,我们通常会使用以下两种PageRoute:MaterialPageRouteCupertinoPageRoute

  • MaterialPageRoute:一个实现了Material Design风格的页面路由,它提供了平台特定的页面切换动画。在Android设备上,页面从底部滑入;在iOS设备上,页面从右侧滑入。如:

    // 使用MaterialPageRoute创建一个新页面
    MaterialPageRoute(builder: (context) => NewPage());
    
  • CupertinoPageRoute:一个实现了Cupertino风格(iOS风格)的页面路由,它提供了iOS平台特定的页面切换动画。如:

    // 使用CupertinoPageRoute创建一个新页面
    CupertinoPageRoute(builder: (context) => NewPage());
    

 Flutter 中,路由技术的另外一个核心概念是 NavigatorNavigator 是一个管理应用页面栈的组件,它负责处理页面之间的跳转、导航以及参数传递等操作。在 Flutter 中,Navigator类是一个关键的组件,它提供了一系列方法来实现页面间的导航

Navigator 是一个管理应用页面栈的组件,它负责处理页面之间的跳转、导航以及参数传递等操作。它通过一个栈结构来管理应用中的页面。当一个新页面被打开时,它会被压入栈顶;当一个页面被关闭时,它会从栈顶弹出。通过对栈的操作,Navigator实现了页面间的跳转和导航。

Navigator 类是一个关键的组件,它提供了一系列方法来实现页面间的导航。包括:

方法 描述
push 将一个新的页面压入栈顶,实现从当前页面跳转到新页面的功能。
pop 将栈顶的页面弹出,实现从当前页面返回到上一个页面的功能。
replace 将栈中的某个页面替换为新的页面。
pushAndRemoveUntil 将一个新的页面压入栈顶,并移除栈中指定条件的页面。
pushNamed 通过页面的名称进行跳转。
popAndPushNamed 弹出当前页面并跳转到指定名称的页面。

为了在应用中使用Navigator,我们需要将其添加到应用的组件树中。在实际开发中,我们通常会在MaterialApp  CupertinoApp 组件中配置 Navigator

// 配置Navigator
MaterialApp(
  home: HomePage(),
  navigatorKey: GlobalKey<NavigatorState>(),
);

接下来,我们可以通过BuildContext来获取NavigatorState对象,进而进行页面间的导航操作。

// 使用push方法跳转到新页面
Navigator.of(context).push(MaterialPageRoute(builder: (context) => NewPage()));

// 使用pop方法返回上一个页面
Navigator.of(context).pop();

本节通过了解Route和Navigator的核心概念、用法以及代码示例,您可以更好地理解和使用 Flutter 中的路由技术。在接下来的章节中,我们将继续深入讲解 Flutter 路由的其他知识点。


在本节中,我们将介绍如何在 Flutter 应用中实现页面间的导航操作,包括页面的跳转、返回以及传递参数等。我们将分别讲解这些操作的原理、用法以及具体的代码示例。


页面跳转是指从当前页面导航到另一个页面的过程。在 Flutter 中,我们可以使用Navigator.push方法将一个新的页面压入栈顶,从而实现页面跳转的功能。

页面跳转的主要步骤如下:

  1. 定义新页面的Route对象,如MaterialPageRouteCupertinoPageRoute
  2. 使用Navigator.push方法跳转到新页面。

例如:

// 定义新页面的Route对象
MaterialPageRoute newPageRoute = MaterialPageRoute(builder: (context) => NewPage());

// 使用Navigator.push方法跳转到新页面
Navigator.of(context).push(newPageRoute);

通过Navigator.push方法,我们可以实现从当前页面跳转到新页面的功能。在实际开发中,我们通常会使用MaterialPageRouteCupertinoPageRoute来创建新页面的Route对象。


页面返回是指从当前页面返回到上一个页面的过程。在 Flutter 中,我们可以使用 Navigator.pop 方法将栈顶的页面弹出,从而实现页面返回的功能。

页面返回的主要步骤如下:

  1. 使用Navigator.pop方法返回上一个页面。
// 使用Navigator.pop方法返回上一个页面
Navigator.of(context).pop();

通过Navigator.pop方法,我们可以实现从当前页面返回到上一个页面的功能。在实际开发中,我们通常会在页面的返回按钮或者手势操作中调用Navigator.pop方法来实现页面返回。


页面替换是指将栈顶的页面替换为一个新的页面。在 Flutter 中,我们可以使用Navigator.replace方法实现这个功能。

要使用页面替换功能,首先需要定义新页面的Route对象。然后调用Navigator.replace方法,传入BuildContext、新Route对象以及要替换的Route对象的标识符作为参数。

例如:

// 定义新页面的Route对象
MaterialPageRoute newPageRoute = MaterialPageRoute(builder: (context) => NewPage());

// 使用Navigator.replace方法替换栈顶的页面
Navigator.of(context).replace(
  oldRoute: ModalRoute.of(context)!,
  newRoute: newPageRoute,
);

页面移除是指将指定的页面从导航堆栈中移除。在 Flutter 中,我们可以使用 Navigator.removeRoute 方法实现这个功能。

要使用页面移除功能,首先需要获取要移除的页面的Route对象。然后调用 Navigator.removeRoute 方法,传入 BuildContext 和要移除的Route对象作为参数。

以下是一个具体的代码示例:

// 获取要移除的页面的Route对象
Route routeToRemove = ModalRoute.of(context)!;

// 使用Navigator.removeRoute方法移除指定页面
Navigator.of(context).removeRoute(routeToRemove);

本节详细讲解了 Flutter 中页面间导航的基本操作,包括页面跳转、页面返回、页面替换和页面移除等。通过了解这些操作的原理、用法和代码示例,您可以更好地理解和使用 Flutter 中的页面间导航操作。在接下来的章节中,我们将继续深入讲解 Flutter 路由的其他知识点。


在本节中,我们将介绍如何在 Flutter 应用中实现路由传参以及接收参数的方法。我们将按照原理、用法和代码示例的顺序,分别讲解这些操作的具体内容。


路由传参是指在跳转到新页面时,将参数传递给新页面,以便新页面根据参数进行相应的操作。在 Flutter 中,我们可以在创建新页面的Route对象时,将参数传递给新页面的构造函数。

以下是一个具体的代码示例:

class NewPage extends StatelessWidget {
  final String data;

  NewPage({required this.data});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('New Page'),
      ),
      body: Center(
        child: Text('Data received: $data'),
      ),
    );
  }
}

// 在跳转时传递参数
MaterialPageRoute newPageRoute = MaterialPageRoute(builder: (context) => NewPage(data: 'Hello, Flutter!'));
Navigator.of(context).push(newPageRoute);

接收参数是指在新页面中获取传递过来的参数,并根据参数进行相应的操作。在 Flutter 中,我们可以在新页面的构造函数中接收传递过来的参数。

以下是一个具体的代码示例:

class NewPage extends StatelessWidget {
  final String data;

  NewPage({required this.data});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('New Page'),
      ),
      body: Center(
        child: Text('Data received: $data'),
      ),
    );
  }
}

返回参数是指在返回上一个页面时,将参数传递回上一个页面。在 Flutter 中,我们可以在调用Navigator.pop方法时,将参数作为方法的第二个参数传递。

以下是一个具体的代码示例:

// 在返回上一个页面时传递参数
Navigator.of(context).pop('Hello, Flutter!');

接收返回参数是指在上一个页面中获取返回的参数,并根据参数进行相应的操作。在 Flutter 中,我们可以在调用Navigator.push方法时,通过then方法获取返回的参数。

以下是一个具体的代码示例:

MaterialPageRoute newPageRoute = MaterialPageRoute(builder: (context) => NewPage());

Navigator.of(context).push(newPageRoute).then((result) {
  print('Data returned: $result');
});

本节详细讲解了 Flutter 中路由传参与接收参数的方法,包括路由传参、接收参数、返回参数和接收返回参数等。通过了解这些操作的原理、用法和代码示例,您可以更好地理解和使用 Flutter 中的路由传参与接收参数。在接下来的章节中,我们将继续深入讲解 Flutter 路由的其他知识点。



在本节中,我们将介绍如何在 Flutter 应用中定义和使用命名路由(静态路由)。我们将按照原理、用法和代码示例的顺序,分别讲解这些操作的具体内容。


命名路由是指为每个路由分配一个名称,以便在进行页面跳转时使用名称来引用路由。在 Flutter 中,我们可以在MaterialAppCupertinoApproutes属性中定义命名路由。

以下是一个具体的代码示例:

MaterialApp(
  initialRoute: '/',
  routes: {
    '/': (context) => HomePage(),
    '/new': (context) => NewPage(),
  },
);

使用命名路由进行页面跳转是指在跳转到新页面时,通过路由名称来引用新页面。在 Flutter 中,我们可以使用Navigator.pushNamed方法进行页面跳转,传入BuildContext和路由名称作为参数。

以下是一个具体的代码示例:

// 使用Navigator.pushNamed方法跳转到新页面
Navigator.of(context).pushNamed('/new');

使用命名路由进行页面返回是指在返回上一个页面时,通过路由名称来引用上一个页面。在 Flutter 中,我们可以使用Navigator.popAndPushNamed方法进行页面返回,传入BuildContext和路由名称作为参数。

以下是一个具体的代码示例:

// 使用Navigator.popAndPushNamed方法返回上一个页面
Navigator.of(context).popAndPushNamed('/');

使用命名路由进行页面替换是指在替换栈顶的页面时,通过路由名称来引用新页面。在 Flutter 中,我们可以使用Navigator.pushReplacementNamed方法进行页面替换,传入BuildContext和路由名称作为参数。

以下是一个具体的代码示例:

// 使用Navigator.pushReplacementNamed方法替换栈顶的页面
Navigator.of(context).pushReplacementNamed('/new');

本节详细讲解了命名路由(静态路由)的定义与使用,包括命名路由的定义、使用命名路由进行页面跳转、页面返回和页面替换等。通过了解这些操作的原理、用法和代码示例,您可以更好地理解和使用 Flutter 中的命名路由(静态路由)。在接下来的章节中,我们将继续深入讲解 Flutter 路由的其他知识点,包括动态路由的定义与使用。


在本节中,我们将介绍如何在 Flutter 应用中定义和使用动态路由。我们将按照原理、用法和代码示例的顺序,分别讲解这些操作的具体内容。


动态路由是指在进行页面跳转时,根据传入的参数生成路由。与命名路由相比,动态路由更加灵活,可以根据需要生成不同的路由。在 Flutter 中,我们可以通过MaterialAppCupertinoApponGenerateRoute属性来定义动态路由。

以下是一个具体的代码示例:

MaterialApp(
  initialRoute: '/',
  onGenerateRoute: (settings) {
    switch (settings.name) {
      case '/':
        return MaterialPageRoute(builder: (context) => HomePage());
      case '/new':
        final String data = settings.arguments as String;
        return MaterialPageRoute(builder: (context) => NewPage(data: data));
      default:
        return MaterialPageRoute(builder: (context) => NotFoundPage());
    }
  },
);

使用动态路由进行页面跳转是指在跳转到新页面时,通过传递参数来生成新页面的路由。在 Flutter 中,我们可以使用Navigator.pushNamed方法进行页面跳转,传入BuildContext、路由名称和参数作为参数。

以下是一个具体的代码示例:

// 使用Navigator.pushNamed方法跳转到新页面,并传递参数
Navigator.of(context).pushNamed('/new', arguments: 'Hello, Flutter!');

使用动态路由进行页面返回是指在返回上一个页面时,通过传递参数来生成上一个页面的路由。在 Flutter 中,我们可以使用Navigator.popAndPushNamed方法进行页面返回,传入BuildContext、路由名称和参数作为参数。

以下是一个具体的代码示例:

// 使用Navigator.popAndPushNamed方法返回上一个页面,并传递参数
Navigator.of(context).popAndPushNamed('/', arguments: 'Hello, Flutter!');

使用动态路由进行页面替换是指在替换栈顶的页面时,通过传递参数来生成新页面的路由。在 Flutter 中,我们可以使用Navigator.pushReplacementNamed方法进行页面替换,传入BuildContext、路由名称和参数作为参数。

以下是一个具体的代码示例:

// 使用Navigator.pushReplacementNamed方法替换栈顶的页面,并传递参数
Navigator.of(context).pushReplacementNamed('/new', arguments: 'Hello, Flutter!');

本节详细讲解了动态路由的定义与使用,包括动态路由的定义、使用动态路由进行页面跳转、页面返回和页面替换等。通过了解这些操作的原理、用法和代码示例,您可以更好地理解和使用 Flutter 中的动态路由。在接下来的章节中,我们将继续深入讲解 Flutter 路由的其他知识点,以帮助您更好地掌握 Flutter 路由的使用方法。


在本节中,我们将对比命名路由和动态路由的特点,以及它们各自适用的场景。通过对比分析,您将更好地理解这两种路由方式的差异,从而在实际项目中选择更合适的路由方式。


下面是命名路由和动态路由的对比:

  1. 定义方式:命名路由通过MaterialAppCupertinoApproutes属性定义,而动态路由通过onGenerateRoute属性定义。
  2. 参数传递:命名路由在进行页面跳转时,需要将参数定义在路由名称中,而动态路由可以通过arguments属性直接传递参数。
  3. 灵活性:动态路由相比于命名路由更加灵活,因为它可以根据传入的参数动态生成路由,而命名路由需要预先定义好所有的路由名称。
  4. 易用性:对于简单的页面跳转,命名路由更加易用,因为它只需要预先定义好路由名称即可。然而,在需要根据参数动态生成路由的场景下,动态路由更加方便。

下面是命名路由和动态路由各自适用的场景:

  1. 命名路由:适用于简单的页面跳转,无需根据参数动态生成路由的场景。例如,从主页跳转到关于页面,或从商品列表页跳转到商品详情页等。
  2. 动态路由:适用于需要根据参数动态生成路由的场景。例如,从用户列表页跳转到用户详情页时,需要根据用户ID生成不同的用户详情页面;或者在一个新闻应用中,根据不同的新闻类别生成不同的新闻列表页面等。

本节通过对比命名路由和动态路由的特点,以及它们各自适用的场景,帮助您更好地理解这两种路由方式的差异。在实际项目中,您可以根据具体需求选择合适的路由方式。总的来说,对于简单的页面跳转,命名路由更加易用;而在需要根据参数动态生成路由的场景下,动态路由更加方便。

在接下来的章节中,我们将继续深入讲解 Flutter 路由的其他知识点,以帮助您更好地掌握 Flutter 路由的使用方法。



在本节中,我们将介绍 go_router 模块的优势与特点。go_router是一个用于 Flutter 的路由库,它提供了一种简洁、强大且易于维护的路由管理方式。

go_router模块有以下优势:

  1. 类型安全go_router模块支持类型安全的路由参数传递,可以有效地减少因参数类型错误而导致的运行时错误。
  2. 代码简洁go_router模块采用声明式的编程方式,可以让您的代码更加简洁、易读和易于维护。
  3. 功能丰富go_router模块提供了多种路由功能,包括命名路由、动态路由、路由守卫、路由重定向等,可以满足各种复杂场景的需求。
  4. 与现有框架兼容go_router模块与其他 Flutter 框架(如Provider、Riverpod、GetX等)兼容良好,可以方便地集成到您的项目中。

从功能上上看, go_router 模块有以下特点:

  1. 命名路由go_router模块支持命名路由,可以让您更方便地管理和跳转到指定页面。
  2. 动态路由go_router模块支持动态路由,可以根据传入的参数生成不同的路由,适用于需要根据参数动态生成路由的场景。
  3. 路由守卫go_router模块支持路由守卫,可以在路由跳转过程中添加条件判断,例如进行身份验证、权限检查等。
  4. 路由重定向go_router模块支持路由重定向,可以根据需要将用户从一个路由重定向到另一个路由。
  5. 浏览器支持go_router模块支持 Flutter Web应用,可以在浏览器中使用URL进行页面跳转。

在本节中,我们将介绍如何安装和配置go_router模块。通过以下步骤,您可以将go_router模块添加到您的 Flutter 项目中,并进行基本的配置。


首先,在您的 Flutter 项目的pubspec.yaml文件中,添加go_router模块的依赖。您可以在pub.dev上查找到go_router模块的最新版本。以下是一个添加依赖的示例:

dependencies:
  flutter:
    sdk: flutter
  go_router: ^2.4.2

添加依赖后,运行flutter pub get命令以下载并安装go_router模块。


在需要使用go_router模块的文件中,导入go_router模块:

import 'package:go_router/go_router.dart';

接下来,定义您的项目中需要使用的路由。创建一个GoRoute对象的列表,每个GoRoute对象代表一个路由。以下是一个定义路由的示例:

final goRoutes = [
  GoRoute(
      path: '/',
      pageBuilder: (context, state) {
        return MaterialPage(child: HomePage());
      }),
  GoRoute(
      path: '/details/:id',
      pageBuilder: (context, state) {
        final id = state.params['id'];
        return MaterialPage(child: DetailsPage(id: id));
      }),
];

在此示例中,我们定义了两个路由:一个是主页(/),另一个是详情页(/details/:id)。详情页的路由路径包含一个动态参数id


创建一个GoRouter对象,并将之前定义的路由列表传递给它:

final goRouter = GoRouter(routes: goRoutes);

GoRouter对象传递给MaterialApp.routerCupertinoApp.router属性。以下是一个配置MaterialApp的示例:

MaterialApp.router(
  routerDelegate: goRouter.routerDelegate,
  routeInformationParser: goRouter.routeInformationParser,
);

本节介绍了如何安装和配置go_router模块。通过添加依赖、导入模块、定义路由、初始化GoRouter对象和配置MaterialApp或CupertinoApp,您可以将go_router模块集成到您的 Flutter 项目中。在接下来的章节中,我们将继续深入讲解go_router模块的使用方法,包括如何进行页面跳转、传递参数、使用路由守卫等。


在本节中,我们将详细介绍如何定义和注册go_router模块中的路由。通过以下步骤,您可以在您的 Flutter 项目中创建和使用go_router模块的路由。


如前文所述,您需要创建一个GoRoute对象的列表来定义路由。每个GoRoute对象都需要包含以下属性:

  • path:路由路径,可以包含动态参数(如/details/:id)。
  • pageBuilder:页面构建器,接收一个BuildContext和GoRouterState对象,返回一个Page对象。您可以在此处创建并返回您的页面(如MaterialPageCupertinoPage等)。

以下是一个定义路由的示例:

final goRoutes = [
  GoRoute(
      path: '/',
      pageBuilder: (context, state) {
        return MaterialPage(child: HomePage());
      }),
  GoRoute(
      path: '/details/:id',
      pageBuilder: (context, state) {
        final id = state.params['id'];
        return MaterialPage(child: DetailsPage(id: id));
      }),
];

在定义了路由列表后,您需要创建一个GoRouter对象,并将路由列表传递给它。这样,您的路由就会被注册到go_router模块中:

final goRouter = GoRouter(routes: goRoutes);

为了更方便地管理和使用路由,您可以为每个路由添加一个name属性。这样,您可以通过路由名称来跳转到指定页面,而无需记住路由路径。以下是一个使用命名路由的示例:

final goRoutes = [
  GoRoute(
      path: '/',
      name: 'home',
      pageBuilder: (context, state) {
        return MaterialPage(child: HomePage());
      }),
  GoRoute(
      path: '/details/:id',
      name: 'details',
      pageBuilder: (context, state) {
        final id = state.params['id'];
        return MaterialPage(child: DetailsPage(id: id));
      }),
];

在为路由添加了名称后,您可以使用GoRouter对象的goNamed方法来跳转到指定页面:

goRouter.goNamed(context, 'details', params: {'id': '123'});

本节详细介绍了如何定义和注册go_router模块中的路由。通过创建GoRoute对象的列表、为路由添加名称和使用GoRouter对象的方法,您可以在您的 Flutter 项目中轻松地创建和使用go_router模块的路由。在接下来的章节中,我们将继续深入讲解go_router模块的使用方法,包括如何进行页面跳转、传递参数、使用路由守卫等。



在本节中,我们将介绍如何使用go_router模块实现基于URL的页面导航。通过以下步骤,您可以在您的 Flutter 项目中使用go_router模块进行页面跳转和参数传递。


使用go_router模块进行页面跳转非常简单。您只需调用GoRouter对象的go方法,并传入当前的BuildContext和目标页面的URL。以下是一个页面跳转的示例:

goRouter.go(context, '/details/123');

在此示例中,我们跳转到了/details/123路径对应的页面。


go_router模块允许您通过URL直接传递参数给目标页面。在定义路由时,您可以在路径中添加动态参数,如/details/:id。然后,在页面跳转时,将参数值直接填充到路径中,如/details/123

在目标页面的pageBuilder方法中,您可以通过GoRouterState对象的params属性获取传递的参数值。以下是一个获取参数值的示例:

final id = state.params['id'];

如前文所述,您可以为路由添加名称,以便更方便地进行页面跳转。在为路由添加了名称后,您可以使用GoRouter对象的goNamed方法来跳转到指定页面,并传递参数:

goRouter.goNamed(context, 'details', params: {'id': '123'});

在此示例中,我们跳转到了名称为details的路由对应的页面,并传递了一个id参数。


本节介绍了如何使用 go_router 模块实现基于 URL 的页面导航。通过调用GoRouter对象的gogoNamed方法,您可以在您的 Flutter 项目中轻松地进行页面跳转和参数传递。在接下来的章节中,我们将继续深入讲解 go_router 模块的使用方法,包括如何使用路由守卫、处理页面过渡动画等。


在本节中,我们将介绍如何使用GoRouter类提供的方法进行页面导航。GoRouter类提供了一系列便捷的方法,使得在 Flutter 项目中进行页面跳转和参数传递变得更加简单。


GoRouter类的go方法允许您通过URL进行页面导航。您只需传入当前的BuildContext和目标页面的URL即可。以下是一个使用go方法进行页面跳转的示例:

goRouter.go(context, '/details/123');

在此示例中,我们跳转到了/details/123路径对应的页面。


GoRouter类的goNamed方法允许您通过路由名称进行页面导航。您需要传入当前的BuildContext、目标页面的路由名称以及一个可选的参数映射。以下是一个使用goNamed方法进行页面跳转的示例:

goRouter.goNamed(context, 'details', params: {'id': '123'});

在此示例中,我们跳转到了名称为details的路由对应的页面,并传递了一个id参数。


GoRouter类的goBack方法允许您返回上一页。您只需传入当前的BuildContext即可。以下是一个使用goBack方法返回上一页的示例:

goRouter.goBack(context);

GoRouter类的goTo方法允许您跳转到指定页面。您需要传入当前的BuildContext、一个GoRouteMatch对象以及一个可选的参数映射。以下是一个使用goTo方法跳转到指定页面的示例:

final match = goRouter.match('/details/123');
goRouter.goTo(context, match, params: {'id': '123'});

在此示例中,我们首先使用match方法获取与URL对应的GoRouteMatch对象,然后使用goTo方法跳转到指定页面,并传递了一个id参数。


本节介绍了如何使用GoRouter类进行页面导航。通过调用GoRouter类的gogoNamedgoBackgoTo方法,您可以在您的 Flutter 项目中轻松地进行页面跳转和参数传递。在接下来的章节中,我们将继续深入讲解go_router模块的使用方法,包括如何使用路由守卫、处理页面过渡动画等。


在使用go_router进行页面导航时,您可能需要在页面间传递参数。本节将介绍如何在使用go_router进行页面跳转时传递参数,并在目标页面中接收这些参数。


要在页面跳转时传递参数,您可以在URL中直接添加动态参数,或者使用命名路由时通过params参数传递。以下是两种传递参数的示例:

通过URL传递参数:

goRouter.go(context, '/details/123');

在此示例中,我们将123作为参数传递给了/details/123路径对应的页面。

通过命名路由传递参数:

goRouter.goNamed(context, 'details', params: {'id': '123'});

在此示例中,我们使用命名路由跳转到details页面,并通过params参数传递了一个id参数。


要在目标页面接收参数,您可以在pageBuilder方法中通过GoRouterState对象的params属性获取传递的参数值。以下是一个在目标页面接收参数的示例:

final id = state.params['id'];

在此示例中,我们从state.params中获取了名为id的参数值。


为了避免在传递参数时出现类型错误,您可以使用GoRouteparamsBuilder属性定义一个类型安全的参数构建器。以下是一个定义类型安全参数构建器的示例:

GoRoute(
  path: '/details/:id',
  pageBuilder: (context, state) {
    final id = state.params['id'];
    return MaterialPage(child: DetailsPage(id: id));
  },
  paramsBuilder: (params) {
    final id = params['id'];
    if (id == null) throw Exception('id is required');
    return {'id': int.parse(id)};
  },
)

在此示例中,我们为GoRoute定义了一个paramsBuilder,它将id参数从字符串转换为整数。这样,在pageBuilder中,我们可以直接使用类型安全的id参数。


本节介绍了如何在使用go_router进行页面导航时传递参数以及在目标页面中接收这些参数。通过在URL中添加动态参数或者使用命名路由时传递params参数,您可以轻松地在页面间传递参数。同时,您还可以使用GoRouteparamsBuilder属性定义类型安全的参数构建器,以避免在传递参数时出现类型错误。在接下来的章节中,我们将继续深入讲解go_router模块的使用方法,包括如何使用路由守卫、处理页面过渡动画等。



深度链接(Deep Linking)是一种允许用户直接打开应用内特定页面的技术。通过深度链接,您可以将用户从网页、广告、电子邮件或其他应用直接导航到您的应用的特定页面,而不仅仅是应用的主页面。这有助于提高用户体验,增加用户参与度,并提高应用的转化率。

在本节中,我们将介绍深度链接的概念,以及如何在使用go_router模块的 Flutter 应用中处理深度链接。


深度链接主要分为两种类型:

  1. 普通深度链接(Standard Deep Links):这种类型的深度链接使用标准的URL格式,例如https://example.com/details/123。当用户点击此类链接时,应用会尝试打开对应的页面。如果应用尚未安装,用户将被重定向到应用商店。
  2. 通用链接(Universal Links):通用链接是一种特殊类型的深度链接,它允许您为一个URL创建一个唯一的关联。当用户点击通用链接时,系统会根据关联信息自动判断是否打开应用或者网页。通用链接在iOS和Android平台上分别称为“通用链接(Universal Links)”和“应用链接(App Links)”。

要在 Flutter 应用中处理深度链接,您需要使用uni_links库。首先,在pubspec.yaml文件中添加uni_links库的依赖项:

dependencies:
  uni_links: ^0.5.1

然后,您需要在应用的入口点(通常是main函数)监听深度链接事件。以下是一个监听深度链接事件的示例:

import 'package:uni_links/uni_links.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // 监听深度链接事件
  StreamSubscription _sub = getUriLinksStream().listen((Uri uri) {
    // 处理深度链接
    print('Received deep link: $uri');
  }, onError: (Object err) {
    print('Failed to handle deep link: $err');
  });

  runApp(MyApp());
}

在此示例中,我们使用getUriLinksStream函数获取深度链接事件流,并监听该流以处理深度链接。


要在使用 go_router  Flutter 应用中处理深度链接,您需要将深度链接的 URL 映射到应用内的页面。以下是一个在 go_router 中处理深度链接的示例:

final goRouter = GoRouter(
  routes: [
    GoRoute(
      path: '/',
      pageBuilder: (context, state) => MaterialPage(child: HomePage()),
    ),
    GoRoute(
      path: '/details/:id',
      pageBuilder: (context, state) {
        final id = state.params['id'];
        return MaterialPage(child: DetailsPage(id: id));
      },
    ),
  ],
  redirect: (state) {
    // 从深度链接中获取参数
    final uri = Uri.parse(state.location);

    // 根据深度链接的URL映射到应用内的页面
    if (uri.path == '/details') {
      final id = uri.queryParameters['id'];
      return '/details/$id';
    }
  },
);

在此示例中,我们为GoRouter定义了一个redirect函数,该函数根据深度链接的URL将用户重定向到应用内的页面。


本节介绍了深度链接的概念,以及如何在使用go_router模块的 Flutter 应用中处理深度链接。深度链接是一种允许用户直接打开应用内特定页面的技术,有助于提高用户体验,增加用户参与度,并提高应用的转化率。在接下来的章节中,我们将继续讲解如何在go_router中处理重定向,以便更好地管理应用的页面跳转逻辑。


在上一节中,我们介绍了深度链接的概念以及如何在 Flutter 应用中处理深度链接。本节将重点介绍如何在使用 go_router 模块的应用中处理深度链接。


首先,我们需要安装uni_links库来处理深度链接。在pubspec.yaml文件中添加uni_links库的依赖项:

dependencies:
  uni_links: ^0.5.1

接下来,我们需要在应用的入口点(通常是main函数)监听深度链接事件。以下是一个监听深度链接事件的示例:

import 'package:uni_links/uni_links.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // 监听深度链接事件
  StreamSubscription _sub = getUriLinksStream().listen((Uri uri) {
    // 处理深度链接
    print('Received deep link: $uri');
  }, onError: (Object err) {
    print('Failed to handle deep link: $err');
  });

  runApp(MyApp());
}

为了处理深度链接,我们需要在go_router中定义与深度链接相关的路由。以下是一个定义了两个路由的示例:

final goRouter = GoRouter(
  routes: [
    GoRoute(
      path: '/',
      pageBuilder: (context, state) => MaterialPage(child: HomePage()),
    ),
    GoRoute(
      path: '/details/:id',
      pageBuilder: (context, state) {
        final id = state.params['id'];
        return MaterialPage(child: DetailsPage(id: id));
      },
    ),
  ],
);

在此示例中,我们定义了两个路由:主页(/)和详情页(/details/:id)。详情页的路由包含一个名为id的参数,该参数将从深度链接的URL中提取。


要在go_router中处理深度链接,我们需要定义一个redirect函数。以下是一个在go_router中处理深度链接的示例:

final goRouter = GoRouter(
  routes: [
    // ...路由定义...
  ],
  redirect: (state) {
    // 从深度链接中获取参数
    final uri = Uri.parse(state.location);

    // 根据深度链接的URL映射到应用内的页面
    if (uri.path == '/details') {
      final id = uri.queryParameters['id'];
      return '/details/$id';
    }
  },
);

在此示例中,我们为GoRouter定义了一个redirect函数,该函数根据深度链接的URL将用户重定向到应用内的页面。


现在我们已经为go_router配置了深度链接处理,我们可以在应用中使用go_router的导航功能。以下是一个使用go_router导航到详情页的示例:

void _onDetailsButtonPressed(BuildContext context) {
  final goRouter = GoRouter.of(context);
  goRouter.go('/details/42');
}

在此示例中,我们使用GoRouter.of函数获取应用的GoRouter实例,然后调用go方法导航到详情页。


本节介绍了如何在使用 go_router 模块的 Flutter 应用中处理深度链接。我们首先安装并配置了uni_links库,然后定义了与深度链接相关的路由。接下来,我们在 go_router 中定义了一个redirect函数来处理深度链接,最后在应用中使用 go_router 进行导航。

通过使用 go_router 处理深度链接,您可以为用户提供更好的体验,从而提高用户参与度和应用转化率。


在本节中,我们将介绍如何在使用go_router模块的 Flutter 应用中实现重定向。重定向是一种在用户尝试访问某个页面时将其引导到另一个页面的方法。这在许多场景中非常有用,例如权限控制、条件渲染等。


要实现重定向,我们需要在GoRouter中定义一个redirect函数。以下是一个简单的重定向函数示例,该函数将用户从/old路径重定向到/new路径:

final goRouter = GoRouter(
  routes: [
    // ...路由定义...
  ],
  redirect: (state) {
    if (state.location == '/old') {
      return '/new';
    }
  },
);

在此示例中,我们为GoRouter定义了一个redirect函数,该函数根据state.location的值将用户重定向到不同的页面。


在实际应用中,我们可能需要根据用户的权限来决定是否允许访问某个页面。以下是一个基于权限的重定向示例:

final goRouter = GoRouter(
  routes: [
    // ...路由定义...
  ],
  redirect: (state) {
    // 检查用户是否具有访问权限
    bool hasPermission = checkUserPermission();

    if (state.location == '/protected' && !hasPermission) {
      return '/login';
    }
  },
);

在此示例中,我们首先检查用户是否具有访问权限。如果用户尝试访问受保护的页面(/protected),但没有权限,我们将用户重定向到登录页面(/login)。


除了基于权限的重定向外,我们还可以根据其他条件来实现重定向。以下是一个基于条件的重定向示例:

final goRouter = GoRouter(
  routes: [
    // ...路由定义...
  ],
  redirect: (state) {
    // 获取设备类型
    final deviceType = getDeviceType();

    if (state.location == '/tablet' && deviceType != 'tablet') {
      return '/mobile';
    }
  },
);

在此示例中,我们首先获取设备类型。如果用户尝试访问适用于平板电脑的页面(/tablet),但设备类型不是平板电脑,我们将用户重定向到适用于手机的页面(/mobile)。


本节介绍了如何在使用go_router模块的 Flutter 应用中实现重定向。我们首先定义了一个重定向函数,然后介绍了如何实现基于权限和条件的重定向。

通过使用go_router实现重定向,您可以更好地管理应用的页面跳转逻辑,从而提高用户体验和应用安全性。在接下来的章节中,我们将继续介绍 go_router 模块的其他功能,如动画导航等。



在本节中,我们将介绍路由守卫的概念以及如何在使用go_router模块的 Flutter 应用中实现路由守卫。路由守卫是一种在用户尝试访问某个页面之前执行的拦截器,可以用于权限控制、数据预加载等场景。


路由守卫的主要作用如下:

  1. 权限控制:在用户访问受保护的页面之前,检查用户是否具有访问权限。如果没有权限,可以重定向到登录页面或显示提示信息。
  2. 数据预加载:在用户访问某个页面之前,预先加载所需的数据。这可以提高页面加载速度,提升用户体验。
  3. 页面跳转控制:在用户访问某个页面之前,根据特定条件决定是否允许页面跳转。

要在go_router模块中实现路由守卫,我们需要为每个需要守卫的路由定义一个guard函数。以下是一个简单的路由守卫示例:

// 路由守卫函数
Future<bool> authGuard(BuildContext context, GoRouterState state) async {
  // 检查用户是否具有访问权限
  bool hasPermission = await checkUserPermission();

  if (!hasPermission) {
    // 如果没有权限,重定向到登录页面
    GoRouter.of(context).go('/login');
    return false;
  }

  return true;
}

final goRouter = GoRouter(
  routes: [
    GoRoute(
      path: '/protected',
      pageBuilder: (context, state) {
        return MaterialPage(child: ProtectedPage());
      },
      guards: [authGuard],
    ),
    // ...其他路由定义...
  ],
);

在此示例中,我们首先定义了一个名为authGuard的路由守卫函数。该函数检查用户是否具有访问权限,如果没有权限,则重定向到登录页面,并返回false以阻止页面跳转。

然后,我们在GoRoute中为受保护的页面(/protected)添加了guards属性,并将authGuard函数作为守卫。


本节介绍了路由守卫的作用以及如何在使用go_router模块的 Flutter 应用中实现路由守卫。路由守卫是一种在用户尝试访问某个页面之前执行的拦截器,可以用于权限控制、数据预加载等场景。通过使用go_router实现路由守卫,您可以更好地管理应用的页面跳转逻辑,从而提高用户体验和应用安全性。


在本节中,我们将深入讨论如何使用go_router模块实现路由守卫。我们将从一个简单的权限控制场景开始,然后讨论如何实现更复杂的路由守卫功能。


假设我们的应用有两个页面:一个登录页面和一个受保护的页面。用户只有在登录后才能访问受保护的页面。我们可以使用go_router的路由守卫功能来实现这个需求。

首先,我们需要为受保护的页面定义一个路由守卫函数,如下所示:

Future<bool> authGuard(BuildContext context, GoRouterState state) async {
  // 检查用户是否已登录
  bool isLoggedIn = await checkUserLoggedIn();

  if (!isLoggedIn) {
    // 如果用户未登录,重定向到登录页面
    GoRouter.of(context).go('/login');
    return false;
  }

  return true;
}

然后,在GoRoute中为受保护的页面添加guards属性,并将authGuard函数作为守卫:

final goRouter = GoRouter(
  routes: [
    GoRoute(
      path: '/protected',
      pageBuilder: (context, state) {
        return MaterialPage(child: ProtectedPage());
      },
      guards: [authGuard],
    ),
    // ...其他路由定义...
  ],
);

现在,只有在用户登录后才能访问受保护的页面。如果用户未登录,他们将被重定向到登录页面。


在某些情况下,我们可能希望在用户访问页面之前预先加载一些数据。我们可以使用路由守卫来实现这个功能。

首先,我们需要定义一个路由守卫函数,用于加载数据:

Future<bool> loadDataGuard(BuildContext context, GoRouterState state) async {
  // 加载所需的数据
  await loadData();

  return true;
}

然后,在GoRoute中为需要预加载数据的页面添加guards属性,并将loadDataGuard函数作为守卫:

final goRouter = GoRouter(
  routes: [
    GoRoute(
      path: '/data',
      pageBuilder: (context, state) {
        return MaterialPage(child: DataPage());
      },
      guards: [loadDataGuard],
    ),
    // ...其他路由定义...
  ],
);

现在,在用户访问数据页面之前,loadDataGuard函数将被调用以加载数据。


本节深入讨论了如何使用go_router模块实现路由守卫。我们通过两个示例展示了如何实现权限控制和数据预加载功能。通过使用go_router实现路由守卫,您可以更好地管理应用的页面跳转逻辑,从而提高用户体验和应用安全性。


在章中,我们将讨论如何使用 go_router 模块为 Flutter 应用程序的页面切换添加自定义过渡动画。默认情况下,Flutter 提供了一些基本的页面过渡效果,但有时我们可能需要自定义这些效果以提高用户体验。通过使用go_router模块,我们可以轻松地实现自定义过渡动画。


我们将首先创建一个简单的淡入淡出过渡动画。为此,我们需要在GoRoutepageBuilder属性中使用CustomTransitionPage组件。以下示例演示了如何为页面切换添加淡入淡出动画:

final goRouter = GoRouter(
  routes: [
    GoRoute(
      path: '/fade',
      pageBuilder: (context, state) {
        return CustomTransitionPage(
          transitionsBuilder: (context, animation, secondaryAnimation, child) {
            return FadeTransition(
              opacity: animation,
              child: child,
            );
          },
          child: FadePage(),
        );
      },
    ),
    // ...其他路由定义...
  ],
);

在这个例子中,我们使用了CustomTransitionPage组件,并将transitionsBuilder属性设置为一个返回FadeTransition的函数。这将使页面切换时产生淡入淡出效果。


接下来,我们将创建一个缩放过渡动画。与上一个示例类似,我们将使用CustomTransitionPage组件,并将transitionsBuilder属性设置为一个返回ScaleTransition的函数。以下示例演示了如何为页面切换添加缩放动画:

final goRouter = GoRouter(
  routes: [
    GoRoute(
      path: '/scale',
      pageBuilder: (context, state) {
        return CustomTransitionPage(
          transitionsBuilder: (context, animation, secondaryAnimation, child) {
            return ScaleTransition(
              scale: animation,
              child: child,
            );
          },
          child: ScalePage(),
        );
      },
    ),
    // ...其他路由定义...
  ],
);

在这个例子中,我们使用了CustomTransitionPage组件,并将transitionsBuilder属性设置为一个返回ScaleTransition的函数。这将使页面切换时产生缩放效果。


我们还可以组合多个过渡动画以创建更复杂的效果。以下示例演示了如何将淡入淡出动画和缩放动画组合在一起:

final goRouter = GoRouter(
  routes: [
    GoRoute(
      path: '/combined',
      pageBuilder: (context, state) {
        return CustomTransitionPage(
          transitionsBuilder: (context, animation, secondaryAnimation, child) {
            return FadeTransition(
              opacity: animation,
              child: ScaleTransition(
                scale: animation,
                child: child,
              ),
            );
          },
          child: CombinedPage(),
        );
      },
    ),
    // ...其他路由定义...
  ],
);

在这个例子中,我们将FadeTransitionScaleTransition组件嵌套在一起,以同时应用淡入淡出和缩放效果。


本章介绍了如何使用go_router模块为 Flutter 应用程序的页面切换添加自定义过渡动画。我们通过三个示例展示了如何实现淡入淡出动画、缩放动画以及组合动画。通过使用go_router模块实现自定义路由过渡动画,可以改善用户体验并为应用添加更好的视觉效果。




F.1.1 Route<T> 类构造器

Route({RouteSettings? settings})

用于初始化 Route。其中 RouteSettings 类为可能对构建 Route 有用的数据。

RouteSettings 具有以下属性:

属性 类型 标签 描述
arguments Object? final 传递到此 Route 的参数。
hashCode int read-only、inherited 此对象的哈希代码。
name String? final Route的名称(例如,“/settings”)。
runtimeType Type read-only、inherited 对象运行时类型的表示形式。

F.1.2 Route<T> 类属性

属性 类型 标签 描述
currentResult T? read-only 当弹出此路径时(参见Navigator.pop ),如果未指定结果或结果为空,将使用此值。
hasActiveRouteBelow bool read-only 此路由下是否至少有一个活动路由。
hashCode int read-only、inherited 此对象的哈希码。
isActive bool read-only 这条路线是否在导航器上。
isCurrent bool read-only 此路由是否是导航器上的最顶层(当前)路由。
isFirst bool read-only 此路由是否是导航器上最底部的活动路由。
navigator NavigatorState? read-only 路由所在的导航器(如果有)。
overlayEntries List<OverlayEntry> read-only 此路由的覆盖条目。
popped Future<T?> read-only 当这条路由从导航器中弹出时,Future就完成了
restorationScopeId ValueListenable<String?> read-only 用于此路由周围的 RestorationScope 的还原范围ID。
runtimeType Type read-only、inherited 对象运行时类型的表示形式。
settings RouteSettings read-only 此路由的设置。
willHandlePopInternally bool read-only 调用 didPop 是否会返回false。

F.1.3 Route<T> 类方法

changedExternalState() → void

每当 导航器(Navigator)以某种可能影响路线的方式更新时调用,以指示路线可能也希望重建。

changedInternalState() → void

每当路由的内部状态改变时调用。

didAdd() → void

将路线添加到导航器后,在 安装 后调用。

didChangeNext(Route? nextRoute) → void

此路由的下一条路线已更改为给定的新路由。

didChangePrevious(Route? previousRoute) → void

此路由的先前路由已更改为给定的新路由。

didComplete(T? result) → void

该路由被弹出或者正被优雅地移除。

didPop(T? result) → bool

弹出此路由的请求。

  • 如果路由可以在内部处理它(例如,因为它有自己的内部状态堆栈),则返回false;
  • 否则返回true(通过返回调用super.didPop的值)。返回false将阻止NavigatorState.pop的默认行为。

didPopNext(Route nextRoute) → void

位于这条路由上方的给定路由已从导航器中弹(pop)出。

didPush() → TickerFuture

当路由被 push 到导航器上时,在安装后调用。

didReplace(Route? oldRoute) → void

当导航器中的路线替换了另一个路由时,在安装后调用。

dispose() → void

丢弃对象使用的任何资源。

install() → void

当路由插入导航器时调用。

willPop() → Future

返回当此 Route 是当前路由 (is current) 时调用 Navigator.maybePop 是否应该执行任何操作。


导航器会将其 Navigator.pages 转换为一个路由堆栈(如果提供的话)。Navigator.pages 中的更改将触发路由堆栈的更新。导航器将更新其路由以匹配其Navigator.pages的新配置。要使用此 API,可以创建一个 Page 子类并为 ·Navigator.pages· 定义一个页面列表。还需要 Navigator.onPopPage 回调以在弹出时正确清理输入页面。

默认情况下,导航器将使用 DefaultTransitionDelegate 来决定路线如何进出屏幕。要自定义它,请定义一个 TransitionDelegate 子类,并将其提供给 Navigator.transitionDelegate

有关使用pages API的更多信息,请参见 Router 部件。


属性 类型 标签 描述
clipBehavior Clip final 根据此选项,内容将被剪切(或不被剪切)。
hashCode int read-only, inherited 此对象的哈希码。
initialRoute String? final 显示的第一个路由的名称。
key Key? final, inherited 控制树中一个 Widget 如何替换另一个 Widget。
observers List final 此 Navigator 的观察者列表。
onGenerateInitialRoutes RouteListFactory final 当 Widget 创建时,如果 initialRoute 不为 null,则调用此函数以生成初始的 Route 对象列表。
onGenerateRoute RouteFactory? final 为给定的 RouteSettings 生成路由时调用。
onPopPage PopPageCallback? final 当调用 pop 时,但当前路由对应于 pages 列表中的 Page 时调用。
onUnknownRoute RouteFactory? final 当 onGenerateRoute 无法生成路由时调用。
pages List<Page> final 用于填充历史记录的页面列表。
reportsRouteUpdateToEngine bool final 当最顶层路由发生变化时,此 Navigator 是否应向引擎报告路由更新消息。
requestFocus bool final 当将新路由推送到 Navigator 时,Navigator 及其最顶层路由是否应请求焦点。
restorationScopeId String? final 恢复 Navigator 的状态的 ID,包括其历史记录。
routeTraversalEdgeBehavior TraversalEdgeBehavior final 控制在路由内部的 Widget 之间定义焦点遍历的焦点范围的第一个和最后一个项目之外的焦点传递。
runtimeType Type read-only, inherited 对象的运行时类型表示。
transitionDelegate TransitionDelegate final 用于决定在页面更新期间路由如何进入或离开屏幕的委托。

方法 返回类型 标签 描述
createElement() StatefulElement inherited 创建一个 StatefulElement 来管理这个小部件在树中的位置。
createState() NavigatorState override 在树中的给定位置创建该小部件的可变状态。
debugDescribeChildren() List<DiagnosticsNode> inherited 返回描述此节点子节点的 DiagnosticsNode 对象列表。
debugFillProperties() void inherited 添加与节点关联的其他属性。
noSuchMethod() dynamic inherited 当访问不存在的方法或属性时调用。
toDiagnosticsNode() DiagnosticsNode inherited 返回用于调试工具和 DiagnosticsNode.toStringDeep 的对象的调试表示。
toString() String inherited 该对象的字符串表示。
toStringDeep() String inherited 返回此节点及其子节点的字符串表示形式。
toStringShallow() String inherited 返回该对象的一行详细描述。
toStringShort() String inherited 该小部件的简短文本描述。

方法 返回类型 描述
canPop(BuildContext context) bool 检查最紧密包围给定上下文的导航器是否可以弹出。
defaultGenerateInitialRoutes(NavigatorState navigator, String initialRouteName) List<Route> 将路由名称转换为一组 Route 对象。
maybeOf(BuildContext context, {bool rootNavigator = false}) NavigatorState? 返回包围给定上下文的最近一次实例的状态,如果有的话。
maybePop<T extends Object?>(BuildContext context, [T? result]) Future<bool> 调用当前路由的 Route.willPop 方法,并根据结果采取相应的操作,可能作为结果弹出路由;返回是否应该将弹出请求视为已处理。
of(BuildContext context, {bool rootNavigator = false}) NavigatorState 返回包围给定上下文的最近一次实例的状态。
pop<T extends Object?>(BuildContext context, [T? result]) void 从最紧密包围给定上下文的导航器中弹出最顶层的路由。
popAndPushNamed<T extends Object?, TO extends Object?>(BuildContext context, String routeName, {TO? result, Object? arguments}) Future<T?> 弹出最紧密包围给定上下文的当前路由,并在其位置推入一个具名路由。
popUntil(BuildContext context, RoutePredicate predicate) void 在最紧密包围给定上下文的导航器上重复调用 pop,直到断言函数返回 true。
push<T extends Object?>(BuildContext context, Route<T> route) Future<T?> 将给定的路由推入最紧密包围给定上下文的导航器中。
pushAndRemoveUntil<T extends Object?>(BuildContext context, Route<T> newRoute, RoutePredicate predicate) Future<T?> 将给定的路由推入最紧密包围给定上下文的导航器中,然后移除所有之前的路由,直到断言函数返回 true。
pushNamed<T extends Object?>(BuildContext context, String routeName, {Object? arguments}) Future<T?> 将一个具名路由推入最紧密包围给定上下文的导航器中。
pushNamedAndRemoveUntil<T extends Object?>(BuildContext context, String newRouteName, RoutePredicate predicate, {Object? arguments}) Future<T?> 将具有给定名称的路由推入最紧密包围给定上下文的导航器中,并移除之前的所有路由,直到断言函数返回 true。
pushReplacement<T extends Object?, TO extends Object?>(BuildContext context, Route<T> newRoute, {TO? result}) Future<T?> 通过推入给定的路由并在新路由动画完成后销毁前一个路由,替换最紧密包围给定上下文的导航器的当前路由。
pushReplacementNamed<T extends Object?, TO extends Object?>(BuildContext context, String routeName, {TO? result, Object? arguments}) Future<T?> 通过推入具名路由并在新路由动画完成后销毁前一个路由,替换最紧密包围给定上下文的导航器的当前路由。
removeRoute(BuildContext context, Route route) void 立即从最紧密包围给定上下文的导航器中移除路由,并调用 Route.dispose 方法进行处理。
removeRouteBelow(BuildContext context, Route anchorRoute) void 立即从最紧密包围给定上下文的导航器中移除位于给定 anchorRoute 下方的路由,并调用 Route.dispose 方法进行处理。
replace<T extends Object?>(BuildContext context, {required Route oldRoute, required Route<T> newRoute}) void 使用新路由替换最紧密包围给定上下文的导航器上的现有路由。
replaceRouteBelow<T extends Object?>(BuildContext context, {required Route anchorRoute, required Route<T> newRoute}) void 使用新路由替换最紧密包围给定上下文的导航器上给定 anchorRoute 下方的现有路由。
restorablePopAndPushNamed<T extends Object?, TO extends Object?> String 将最紧密包围给定上下文的导航器中的当前路由弹出并推入一个具名路由。
restorablePush<T extends Object?> String 在最紧密包围给定上下文的导航器中推入一个新路由。
restorablePushAndRemoveUntil<T extends Object?> String 在最紧密包围给定上下文的导航器中推入一个新路由,并删除之前的所有路由,直到断言函数返回 true。
restorablePushNamed<T extends Object?> String 在最紧密包围给定上下文的导航器中推入一个具名路由。
restorablePushNamedAndRemoveUntil<T extends Object?> String 将具有给定名称的路由推入最紧密包围给定上下文的导航器中,并删除之前的所有路由,直到断言函数返回 true。
restorablePushReplacement<T extends Object?, TO extends Object?> String 通过推入一个新路由并在新路由动画完成后销毁前一个路由,替换最紧密包围给定上下文的导航器的当前路由。
restorablePushReplacementNamed<T extends Object?, TO extends Object?> String 通过推入具名路由并在新路由动画完成后销毁前一个路由,替换最紧密包围给定上下文的导航器的当前路由。
restorableReplace<T extends Object?> String 使用新路由替换最紧密包围给定上下文的导航器上的现有路由。
restorableReplaceRouteBelow<T extends Object?> String 使用新路由替换最紧密包围给定上下文的导航器上给定 anchorRoute 下方的现有路由。

【注意】:GoRouter 和 GoRoute 是两个类。

  1. GoRouter 类是 go_router 的核心类,负责管理整个应用程序的路由系统。它维护了一个路由配置(RouteConfiguration),管理路由信息的解析(GoRouteInformationParser)和提供(GoRouteInformationProvider),以及控制页面导航和路由状态的变化。GoRouter 类提供了一系列方法来处理路由的导航、添加监听器、刷新路由等操作,如 push、pop、replace、addListener、refresh 等。
  2. GoRoute 类是表示单个路由的对象。它定义了一个具体的路由路径、参数和相关的操作。每当用户导航到一个新的路由时,GoRouter 会创建一个对应的 GoRoute 对象,并将其添加到路由堆栈中。GoRoute 类提供了一些方法来处理路由的生成、匹配、跳转和导航等操作,如 go、goNamed、namedLocation、replaceNamed 等。
    总结来说,GoRouter 类是整个路由系统的管理者,负责路由的整体控制和状态管理,而 GoRoute 类是单个路由的表示和操作者,负责具体路由的生成、匹配和导航等操作。
    例如:
import 'package:go_router/go_router.dart';

// 定义路由配置
final routeConfig = RouteConfiguration(
 routes: {
   '/': (context) => HomePage(), // 根路由
   '/settings': (context) => SettingsPage(), // 设置页面路由
   '/profile/:username': (context, state) => ProfilePage(username: state.params['username']), // 用户个人资料页面路由
 },
);

// 创建 GoRouter 实例
final goRouter = GoRouter(
 routes: routeConfig.routes,
 errorPageBuilder: (context, state) => ErrorPage(), // 错误页面
);

// 在 MaterialApp 或 CupertinoApp 中使用 goRouter.routerDelegate 作为路由委托
MaterialApp(
 ...
 routerDelegate: goRouter.routerDelegate,
 backButtonDispatcher: goRouter.backButtonDispatcher,
 ...
);

// 在任何需要进行路由导航的地方,可以通过 goRouter 实例进行操作
void navigateToSettings() {
 goRouter.pushNamed('/settings');
}

void navigateToProfile(String username) {
 goRouter.goNamed('/profile/:username', pathParameters: {'username': username});
}

go_router 模块中提供了一个 GoRouter 对象,用于定义和管理应用程序的路由。

GoRouter 是 go_router 库的核心类,它负责路由的注册、导航和页面渲染。通过创建一个 GoRouter 对象,你可以配置应用程序的路由规则并管理不同页面之间的导航。

在创建 GoRouter 对象时,你可以指定一组路由规则。每个路由规则由一个路径模式和一个处理程序(Handler)组成。路径模式是一个字符串,用于匹配特定的 URL 路径。处理程序则定义了当路径与模式匹配时要执行的操作,通常是展示相应的页面。

GoRouter 对象提供了多个方法来管理路由和导航,包括:

  • push:将指定的路径推入导航堆栈,导航到相应的页面。
  • pop:将当前页面从导航堆栈中弹出,返回上一个页面。
  • replace:替换当前页面为指定的路径对应的页面。
  • navigateTo:根据给定的路径导航到相应的页面。

除了基本的导航功能外,GoRouter 还支持以下特性:

  • 参数传递:你可以在导航时传递参数,以便在目标页面上使用。
  • 嵌套路由:你可以在页面中嵌套多个 GoRouter 对象,实现更复杂的路由结构。
  • 路由守卫:你可以定义路由守卫,用于在导航到页面之前执行一些操作,如验证用户权限等。

以下是 GoRouter 对象的属性和方法的解析:

在 pub.dev 文档中,GoRoute 类的文档地址为: https://pub.dev/documentation/go_router/latest/go_router/GoRouter-class.html

GoRouter 对象的属性

属性 类型 标签 描述
backButtonDispatcher BackButtonDispatcher final 用于配置 Router 的 BackButtonDispatcher。
configuration RouteConfiguration late final GoRouter 使用的路由配置。
hashCode int read-only inherited 此对象的哈希码。
hasListeners bool read-only inherited 当前是否有任何监听器已注册。
location String read-only 获取当前位置。
routeInformationParser GoRouteInformationParser late final override-getter GoRouter 使用的路由信息解析器。
routeInformationProvider GoRouteInformationProvider late final override-getter GoRouter 使用的路由信息提供器。
routerDelegate GoRouterDelegate late final override-getter 路由代理。在 MaterialApp 或 CupertinoApp 的 .router() 构造函数中提供此对象。
runtimeType Type read-only inherited 对象的运行时类型表示。

GoRouter 对象的方法

方法 返回类型 标签 描述
addListener(VoidCallback listener) void inherited 注册一个闭包,在对象发生变化时调用。
canPop() bool 如果可以弹出至少两个或更多路由,则返回 true。
dispose() void 释放对象使用的任何资源。调用此方法后,对象将处于不可用状态,应将其丢弃(在对象被处理后,调用 addListener 将引发异常)。
go(String location, {Object? extra}) void 导航到指定的 URI 位置,可选包含查询参数,例如 /family/f2/person/p1?color=blue。
goNamed(String name, {Map<String, String> pathParameters = const <String, String>{}, Map<String, dynamic> queryParameters = const <String, dynamic>{}, Object? extra}) void 导航到指定的命名路由,可选包含参数,例如 name=‘person’,pathParameters={‘fid’: ‘f2’, ‘pid’: ‘p1’}。
namedLocation(String name, {Map<String, String> pathParameters = const <String, String>{}, Map<String, dynamic> queryParameters = const <String, dynamic>{}}) String 根据路由名称和参数获取位置。这对于重定向到命名位置非常有用。
noSuchMethod(Invocation invocation) dynamic inherited 当访问不存在的方法或属性时调用。
notifyListeners() void inherited 调用所有注册的监听器。
pop<T extends Object?>([T? result]) void 弹出当前屏幕上最顶部的路由。
push<T extends Object?>(String location, {Object? extra}) Future<T?> 将 URI 位置推入页面堆栈中,可选包含查询参数,例如 /family/f2/person/p1?color=blue。
pushNamed<T extends Object?>(String name, {Map<String, String> pathParameters = const <String, String>{}, Map<String, dynamic> queryParameters = const <String, dynamic>{}, Object? extra}) Future<T?> 将命名路由推入页面堆栈中,可选包含参数,例如 name=‘person’,pathParameters={‘fid’: ‘f2’, ‘pid’: ‘p1’}。
pushReplacement<T extends Object?>(String location, {Object? extra}) Future<T?> 使用给定的 URL 位置替换页面堆栈中的最顶部页面,可选包含查询参数,例如 /family/f2/person/p1?color=blue。
pushReplacementNamed<T extends Object?>(String name, {Map<String, String> pathParameters = const <String, String>{}, Map<String, dynamic> queryParameters = const <String, dynamic>{}, Object? extra}) Future<T?> 使用命名路由替换页面堆栈中的最顶部页面,可选包含参数,例如 name=‘person’,pathParameters={‘fid’: ‘f2’, ‘pid’: ‘p1’}。
refresh() void 刷新路由。
removeListener(VoidCallback listener) void inherited 从注册的闭包列表中移除先前注册的闭包,这些闭包在对象发生变化时被通知。
replace(String location, {Object? extra}) Future<T?> 将页面堆栈中的最顶部页面替换为给定页面,但将其视为同一页面。
replaceNamed(String name, {Map<String, String> pathParameters = const <String, String>{}, Map<String, dynamic> queryParameters = const <String, dynamic>{}, Object? extra}) Future<T?> 使用命名路由替换最顶部的页面,并保留页面键和可选参数。
restore(RouteMatchList matchList) void 恢复 RouteMatchList。
toString() String inherited 返回对象的字符串表示形式。

GoRouter 对象的静态属性和静态方法

属性 类型 标签 描述
optionURLReflectsImperativeAPIs bool read / write 命令式API是否影响浏览器地址栏。
方法 返回类型 描述
maybeOf(BuildContext context) GoRouter 小部件树中的当前GoRouter(如果有)。
of(BuildContext context) GoRouter 在小部件树中查找当前的GoRouter。
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。