Flutter Development Notes: Flutter Routing Technology

Flutter
Flutter Development Notes: Routing Technology

- Article information -
Author: Jack Lee (jcLee95)
Visit me at: https://jclee95.blog.csdn.net
Email: [email protected].
Shenzhen China
Address of this article:https://blog.csdn.net/qq_28550263/article/details/131376141

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

Next section: " Practical Case: Using go_router to Build a Mobile Music Application "

Table of contents


1 Overview

1.1 Introduction to Mobile Routing

Routing technology is a very important part of mobile application development. Routing technology is responsible for managing key functions such as jumping, navigation, and parameter passing between pages in the application. In mobile applications, an efficient and easy-to-maintain routing system is of great significance for improving development efficiency and user experience.

1.2 Content navigation of this article

This article will explain in detail the routing technology in Flutter mobile application development, covering the following aspects:

  • Basic knowledge of Flutter routing, including core concepts, basic operations, and parameter passing;
  • The definition, use and comparison of named routing and dynamic routing;
  • go_routerIntroduction to modules, including installation, configuration, definition and registration of routes, etc.;
  • Use to go_routerimplement advanced features such as page navigation, deep link handling, and redirection;
  • Realization of routing guard and routing transition animation;
  • Through actual combat cases, it shows how to use to go_routerbuild a complete mobile application.

By studying this article, you can master the basic principles and practical methods of Flutter routing technology, and lay a solid foundation for developing high-quality mobile applications.

2. Flutter Routing Basics

2.1 The core of routing: Route and Navigator

In Flutter , the core concept of routing technology includes two elements: Route and Navigator .

2.1.1 Route

Route represents a page in the application, which contains information such as the layout, logic, and life cycle of the page. In Flutter , Route is usually a PageRouteclass that inherits from .

PageRouteIs an abstract class that represents a Navigatorpage that can be used. It contains properties such as page construction methods, transition animations, and page lifecycle callbacks. In actual development, we usually use the following two PageRoutes: MaterialPageRouteor CupertinoPageRoute:

  • MaterialPageRoute: A page router that implements the Material Design style, which provides platform-specific page switching animations. On Android, the page slides in from the bottom; on iOS, the page slides in from the right. like:

    // 使用MaterialPageRoute创建一个新页面
    MaterialPageRoute(builder: (context) => NewPage());
    
  • CupertinoPageRoute: A page router that implements Cupertino style (iOS style), which provides iOS platform-specific page switching animations. like:

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

2.1.2 Navigator

In Flutter , another core concept of routing technology is Navigator . Navigator is a component that manages the application page stack, and it is responsible for handling operations such as jumping between pages, navigation, and parameter passing. In Flutter , the Navigator class is a key component that provides a series of methods to navigate between pages

Navigator is a component that manages the application page stack, and it is responsible for handling operations such as jumping between pages, navigation, and parameter passing. It manages the pages in the application through a stack structure. When a new page is opened, it is pushed onto the stack; when a page is closed, it is popped from the stack. Through the operation of the stack, Navigator realizes the jump and navigation between pages.

The Navigator class is a key component that provides a series of methods to navigate between pages. include:

method describe
push Push a new page to the top of the stack to realize the function of jumping from the current page to the new page.
pop Pop the page at the top of the stack to realize the function of returning from the current page to the previous page.
replace Replace a page in the stack with a new page.
pushAndRemoveUntil Push a new page onto the top of the stack, and remove the page with the specified condition from the stack.
pushNamed Jump by page name.
popAndPushNamed Pop up the current page and jump to the page with the specified name.

In order to use it in the application Navigator, we need to add it to the application's component tree. In actual development, we usually configure Navigator in MaterialApp or CupertinoApp components .

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

Next, we can obtain the NavigatorState object through BuildContext, and then perform navigation operations between pages.

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

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

2.1.3 Summary

In this section, by understanding the core concepts, usage, and code samples of Route and Navigator, you can better understand and use the routing technology in Flutter . In the next chapters, we will continue to explain other knowledge points of Flutter routing in depth.

2.2 Basic operation of navigation between pages

In this section, we will introduce how to implement navigation operations between pages in the Flutter application, including page jump, return, and parameter passing. We will explain the principles, usage and specific code examples of these operations respectively.

2.2.1 Page Jump

Page jumping refers to the process of navigating from the current page to another page. In Flutter , we can use Navigator.pushmethods to push a new page onto the top of the stack, thereby realizing the function of page jump.

The main steps of page jump are as follows:

  1. An object defining a new page Route, such as MaterialPageRouteor CupertinoPageRoute.
  2. Use Navigator.pushthe method to jump to a new page.

For example:

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

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

Through Navigator.pushthe method, we can realize the function of jumping from the current page to the new page. In actual development, we usually use MaterialPageRouteor CupertinoPageRouteto create the Route object of the new page.

2.2.2 Page return

Page return refers to the process of returning from the current page to the previous page. In Flutter , we can use Navigator.popthe method to pop the page at the top of the stack to realize the function of returning the page.

The main steps of page return are as follows:

  1. Use Navigator.popthe method to return to the previous page.
// 使用Navigator.pop方法返回上一个页面
Navigator.of(context).pop();

Through Navigator.popthe method, we can realize the function of returning from the current page to the previous page. In actual development, we usually call Navigator.popthe method in the back button or gesture operation of the page to return the page.

2.2.3 Page Replacement

Page replacement refers to replacing the page at the top of the stack with a new page. In Flutter , we can use the Navigator.replace method to achieve this functionality.

To use the page replacement function, you first need to define the Route object of the new page. Then call the Navigator.replace method, passing in the BuildContext, the new Route object, and the identifier of the Route object to be replaced as parameters.

For example:

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

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

2.2.4 Page removal

Page removal refers to removing the specified page from the navigation stack. In Flutter , we can use the Navigator.removeRoute method to achieve this function.

To use the page removal function, you first need to obtain the Route object of the page to be removed. Then call the Navigator.removeRoute method, passing in the BuildContext and the Route object to be removed as parameters.

Here is a concrete code example:

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

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

2.2.5 Summary

This section explains in detail the basic operations of navigation between pages in Flutter , including page jump, page return, page replacement, and page removal. By understanding the principles, usage, and code samples of these operations, you can better understand and use the inter-page navigation operations in Flutter . In the next chapters, we will continue to explain other knowledge points of Flutter routing in depth.

2.3 Routing pass and receive parameters

In this section, we will introduce how to implement routing parameter passing and methods of receiving parameters in Flutter applications. We will explain the specific content of these operations in the order of principle, usage and code examples.

2.3.1 Route parameter passing

Routing parameter passing refers to passing parameters to the new page when jumping to a new page, so that the new page can perform corresponding operations according to the parameters. In Flutter , we can Routepass parameters to the constructor of the new page when creating the object of the new page.

Here is a concrete code example:

class NewPage extends StatelessWidget {
    
    
  final String data;

  NewPage({
    
    required this.data});

  
  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);

2.3.2 Receive parameters

Receiving parameters refers to obtaining the passed parameters in the new page, and performing corresponding operations according to the parameters. In Flutter , we can receive the passed parameters in the constructor of the new page.

Here is a concrete code example:

class NewPage extends StatelessWidget {
    
    
  final String data;

  NewPage({
    
    required this.data});

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

2.3.3 Return parameters

The return parameter refers to passing the parameter back to the previous page when returning to the previous page. In FlutterNavigator.pop , we can pass parameters as the second parameter of the method when calling the method.

Here is a concrete code example:

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

2.3.4 Receive return parameters

Receiving return parameters refers to obtaining the returned parameters in the previous page, and performing corresponding operations according to the parameters. In Flutter , we can get the returned parameters Navigator.pushthrough the method when calling the method.then

Here is a concrete code example:

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

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

2.3.5 Summary

This section explains in detail the methods of routing and receiving parameters in Flutter , including routing parameters, receiving parameters, returning parameters, and receiving return parameters. By understanding the principles, usage, and code examples of these operations, you can better understand and use routing parameters in Flutter to pass and receive parameters. In the next chapters, we will continue to explain other knowledge points of Flutter routing in depth.

3. Named routing and dynamic routing

3.1 Definition and use of named routes

In this section, we will describe how to define and use named routes (static routes) in a Flutter application. We will explain the specific content of these operations in the order of principle, usage and code examples.

3.1.1 Definition of named routes

Naming routes refers to assigning a name to each route, so that the name can be used to refer to the route when performing page jumps. In Flutter , we can define named routes in properties of MaterialAppor .CupertinoApproutes

Here is a concrete code example:

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

3.1.2 Use named routing for page jumping

Using named routes for page jumping means that when jumping to a new page, the new page is referenced by the route name. In Flutter , we can use Navigator.pushNamedthe method to jump to the page, and pass in the BuildContext and the route name as parameters.

Here is a concrete code example:

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

3.1.3 Use named routes for page return

Using named routes for page return refers to referring to the previous page through the route name when returning to the previous page. In Flutter , we can use Navigator.popAndPushNamedthe method to return the page, passing in the BuildContext and the route name as parameters.

Here is a concrete code example:

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

3.1.4 Using named routes for page replacement

Page replacement using named routes means that when replacing the page at the top of the stack, the new page is referred to by the route name. In Flutter , we can use Navigator.pushReplacementNamedmethods for page replacement, passing in BuildContext and route name as parameters.

Here is a concrete code example:

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

3.1.5 Summary

This section explains in detail the definition and use of named routes (static routes), including the definition of named routes, page jumps using named routes, page return and page replacement, etc. By understanding the principles, usage, and code samples of these operations, you can better understand and use named routes (static routes) in Flutter . In the next chapters, we will continue to explain other knowledge points of Flutter routing in depth, including the definition and use of dynamic routing.

3.2 Definition and use of dynamic routing

In this section, we'll cover how to define and use dynamic routes in a Flutter app. We will explain the specific content of these operations in the order of principle, usage and code examples.

3.2.1 Definition of dynamic routing

Dynamic routing refers to generating routes based on incoming parameters when performing page jumps. Compared with named routing, dynamic routing is more flexible and can generate different routes as needed. In Flutter , we can define dynamic routes through MaterialAppor CupertinoAppproperties .onGenerateRoute

Here is a concrete code example:

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());
    }
  },
);

3.2.2 Use dynamic routing for page jump

Using dynamic routing for page jump refers to generating a new page route by passing parameters when jumping to a new page. In Flutter , we can use Navigator.pushNamedthe method to jump to the page, and pass in the BuildContext, route name and parameters as parameters.

Here is a concrete code example:

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

3.2.3 Use dynamic routing for page return

Using dynamic routing for page return refers to generating the route of the previous page by passing parameters when returning to the previous page. In Flutter , we can use Navigator.popAndPushNamedthe method to return the page, passing in the BuildContext, routing name and parameters as parameters.

Here is a concrete code example:

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

3.2.4 Using dynamic routing for page replacement

Page replacement using dynamic routing refers to a route that generates a new page by passing parameters when replacing the page at the top of the stack. In Flutter , we can use Navigator.pushReplacementNamedmethods for page replacement, passing in BuildContext, route name and parameters as parameters.

Here is a concrete code example:

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

3.1.5 Summary

This section explains the definition and use of dynamic routing in detail, including the definition of dynamic routing, page jumping, page return, and page replacement using dynamic routing. By understanding the principles, usage, and code samples of these operations, you can better understand and use dynamic routing in Flutter . In the next chapters, we will continue to explain other knowledge points of Flutter routing in depth, so as to help you better understand how to use Flutter routing.

3.3 Comparison between named routing and dynamic routing

In this section, we will compare the characteristics of named routing and dynamic routing, and the scenarios where they are applicable. Through comparative analysis, you will better understand the differences between these two routing methods, so that you can choose a more suitable routing method in actual projects.

3.3.1 Comparison between named routing and dynamic routing

The following is a comparison between named routing and dynamic routing:

  1. Definition method : Named routes are defined through MaterialAppor CupertinoAppattributes routes, while dynamic routes onGenerateRouteare defined through attributes.
  2. Parameter passing : When a named route performs page jumps, parameters need to be defined in the route name, while dynamic routes can argumentsdirectly pass parameters through attributes.
  3. Flexibility : Dynamic routing is more flexible than named routing because it can dynamically generate routes based on incoming parameters, while named routing needs to pre-define all routing names.
  4. Ease of use : For simple page jumps, named routing is easier to use, because it only needs to pre-define the routing name. However, dynamic routing is more convenient in scenarios where routes need to be dynamically generated based on parameters.

3.3.2 Applicable scenarios

The following are the applicable scenarios for named routing and dynamic routing:

  1. Named routing : suitable for simple page jumps without dynamically generating routes based on parameters. For example, jumping from the homepage to the about page, or jumping from the product list page to the product details page, etc.
  2. Dynamic routing : Applicable to scenarios where routes need to be dynamically generated based on parameters. For example, when jumping from the user list page to the user details page, it is necessary to generate different user details pages according to the user ID; or in a news application, generate different news list pages according to different news categories, etc.

3.3.3 Summary

This section helps you better understand the differences between named routing and dynamic routing by comparing the features of named routing and dynamic routing, as well as their applicable scenarios. In actual projects, you can choose an appropriate routing method according to your specific needs. In general, named routing is easier to use for simple page jumps; dynamic routing is more convenient in scenarios where routing needs to be dynamically generated based on parameters.

In the next chapters, we will continue to explain other knowledge points of Flutter routing in depth, so as to help you better understand how to use Flutter routing.

4. Introduction to go_router module

4.1 Features of go_router module

In this section, we will introduce go_routerthe advantages and features of the module. go_routeris a routing library for Flutter , which provides a simple, powerful and easy-to-maintain routing management method.

The solution go_routermodule has the following advantages:

  1. Type safety : go_routerThe module supports type-safe routing parameter passing, which can effectively reduce runtime errors caused by wrong parameter types.
  2. Concise code : go_routerThe module adopts declarative programming method, which can make your code more concise, easy to read and easy to maintain.
  3. Rich functions : go_routerThe module provides a variety of routing functions, including named routing, dynamic routing, routing guards, routing redirection, etc., which can meet the needs of various complex scenarios.
  4. Compatible with existing frameworks : go_routerThe module is well compatible with other Flutter frameworks (such as Provider, Riverpod, GetX, etc.), and can be easily integrated into your project.

From a functional point of view, go_routerthe module has the following characteristics:

  1. Named routing : go_routerThe module supports named routing, which allows you to manage and jump to specified pages more conveniently.
  2. Dynamic routing : go_routerThe module supports dynamic routing and can generate different routes according to the parameters passed in. It is suitable for scenarios where routes need to be dynamically generated according to parameters.
  3. Routing guard : go_routerThe module supports routing guards, which can add conditional judgments during the routing jump process, such as identity verification, permission checks, etc.
  4. Route redirection : go_routerThe module supports route redirection, which can redirect users from one route to another as needed.
  5. Browser Support : go_routerThe module supports Flutter web applications, and URLs can be used to jump pages in the browser.

4.2 Install and configure go_router module

In this section, we will describe how to install and configure go_routerthe module. Through the following steps, you can go_routeradd the module to your Flutter project and perform basic configuration.

4.2.1 Add dependencies

First, in your Flutter project's pubspec.yamlfiles, add go_routerthe module's dependencies. You can find the latest version of the module on pub.dev . go_routerHere is an example of adding dependencies:

dependencies:
  flutter:
    sdk: flutter
  go_router: ^2.4.2

After adding dependencies, run flutter pub getthe command to download and install go_routerthe module.

4.2.2 Import go_router module

In the file that needs to use go_routerthe module, import go_routerthe module:

import 'package:go_router/go_router.dart';

4.2.3 Define routes

Next, define the routes you need to use in your project. Create a GoRoutelist of objects, each GoRouterepresenting a route. Here is an example of defining a route:

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));
      }),
];

In this example, we define two routes: one for the home page ( /) and one for the details page ( /details/:id). The routing path of the details page contains a dynamic parameter id.

4.2.4 Initialize the GoRouter object

Create an GoRouterobject and pass it the list of previously defined routes:

final goRouter = GoRouter(routes: goRoutes);

4.2.5 Configuring MaterialApp or CupertinoApp

Pass GoRouterthe object to MaterialApp.routeror CupertinoApp.routerproperty. Here is an MaterialAppexample configuration:

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

4.2.6 Summary

This section describes how to install and configure go_routerthe module. You can integrate go_routermodules into your Flutter project by adding dependencies, importing modules, defining routes, initializing GoRouter objects, and configuring MaterialApp or CupertinoApp. In the next chapters, we will continue to explain go_routerhow to use the module in depth, including how to jump pages, pass parameters, use routing guards, etc.

4.3 Define and register routes

In this section, we'll detail how to define and register go_routerroutes in a module. With the following steps, you can create and use a module's route in your Flutter project.go_router

4.3.1 Define routes

As mentioned earlier, you need to create a GoRoutelist of objects to define routes. Each GoRouteobject needs to contain the following properties:

  • path: route path, which can contain dynamic parameters (eg /details/:id.
  • pageBuilder: The page builder receives a BuildContext and GoRouterState object and returns a Page object. Here you can create and return your pages (eg MaterialPage, CupertinoPageetc).

Here is an example of defining a route:

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));
      }),
];

4.3.2 Register routing

After defining the route list, you need to create an GoRouterobject and pass it the route list. This way, your routes will be registered in go_routerthe module:

final goRouter = GoRouter(routes: goRoutes);

4.3.3 Using named routes

In order to manage and use routes more conveniently, you can add an nameattribute to each route. In this way, you can jump to the specified page through the route name without remembering the route path. Here is an example using named routes:

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));
      }),
];

After adding a name to the route, you can use GoRouterthe object's goNamedmethods to jump to the specified page:

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

4.3.4 Summary

This section details how to define and register go_routerroutes in the module. By creating GoRoutea list of objects, adding a name to the route, and using the object's methods, you can easily create and use a module's routes GoRouterin your Flutter project. go_routerIn the next chapters, we will continue to explain go_routerhow to use the module in depth, including how to jump pages, pass parameters, use routing guards, etc.

5. Use go_router to realize page navigation

5.1 URL-based navigation

In this section, we'll cover how to go_routerimplement URL-based page navigation using modules. Through the following steps, you can use modules in your Flutter project for page jumping and parameter passing.go_router

5.1.1 Page Jump

go_routerPage jumping using modules is very simple. You simply call GoRouterthe object's gomethod, passing in the current BuildContextand target page URLs. The following is an example of a page jump:

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

In this example, we jump to /details/123the page corresponding to the path.

5.1.2 Passing parameters

go_routerModules allow you to pass parameters directly to the target page via the URL. When defining a route, you can add dynamic parameters to the route, eg /details/:id. Then, when the page jumps, fill the parameter value directly into the path, eg /details/123.

In the method of the target page pageBuilder, you can get the passed parameter value through the property GoRouterStateof the object . paramsHere is an example of getting parameter values:

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

5.1.3 Using named routes

As mentioned above, you can add a name to the route for easier page jumping. After adding a name to the route, you can use GoRouterthe object's goNamedmethod to jump to the specified page and pass parameters:

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

In this example, we jump to detailsthe page corresponding to the route named and pass a idparameter.

5.1.4 Summary

This section describes how to go_routerimplement URL-based page navigation using the module. By calling GoRouterthe object's goor method, you can easily perform page jumps and parameter passing in goNamedyour Flutter project. In the next chapters, we will continue to explain in depth go_routerhow to use the module, including how to use route guards, handle page transition animations, and more.

5.2 Navigation using the GoRouter class

In this section, we will introduce how to use GoRouterthe methods provided by the class for page navigation. GoRouterThe class provides a series of convenient methods, making page jumping and parameter passing easier in the Flutter project.

5.2.1 Navigate using the go method

GoRouterThe methods of the class goallow you to navigate pages by URL. You simply pass in the current BuildContextand target page URLs. The following is an goexample of using the method to jump to the page:

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

In this example, we jump to /details/123the page corresponding to the path.

5.2.2 Navigating using the goNamed method

GoRouterThe methods of the class goNamedallow you to page navigate by route name. You need to pass in the current BuildContext, target page's route name and an optional parameter map. The following is an goNamedexample of using the method to jump to the page:

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

In this example, we jump to detailsthe page corresponding to the route named and pass a idparameter.

5.2.3 Use the goBack method to return to the previous page

GoRouterThe methods of the class goBackallow you to go back to the previous page. You just pass in the current BuildContextone. Here's an goBackexample of using the method to return to the previous page:

goRouter.goBack(context);

5.2.4 Use the goTo method to jump to the specified page

GoRouterThe methods of the class goToallow you to jump to a specified page. You need to pass in the current BuildContext, an GoRouteMatchobject, and an optional parameter map. The following is an example of using goTothe method to jump to a specified page:

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

In this example, we first use matchthe method to obtain the object corresponding to the URL GoRouteMatch, and then use goTothe method to jump to the specified page and pass a idparameter.

5.2.5 Summary

This section describes how to use GoRouterclasses for page navigation. By calling the , , and methods GoRouterof the class , you can easily perform page jumps and parameter passing in your Flutter project. In the next chapters, we will continue to explain in depth how to use the module, including how to use route guards, handle page transition animations, and more.gogoNamedgoBackgoTogo_router

5.3 Passing between pages to participate in receiving parameters

When go_routernavigating through pages with , you may need to pass parameters between pages. This section will introduce how to go_routerpass parameters when using the page jump, and receive these parameters in the target page.

5.3.1 Passing parameters when page jumps

To pass parameters when redirecting pages, you can directly add dynamic parameters to the URL, or paramspass parameters when using named routes. Here are two examples of passing parameters:

Pass parameters via URL:

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

In this example, we 123pass as a parameter /details/123the page corresponding to the path.

Pass parameters through named routes:

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

In this example, we use the named route to jump to detailsthe page, paramspassing a idparameter via the parameter.

5.3.2 Receive parameters on the target page

To receive parameters on the target page, you can obtain the passed parameter values ​​through the properties of the object pageBuilderin the method . Here is an example of receiving parameters on the target page:GoRouterStateparams

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

In this example, state.paramswe get idthe value of the parameter named from it.

5.3.3 Pass parameters in a type-safe way

To avoid type errors when passing parameters, you can define a type-safe parameter builder using the attribute GoRoute. paramsBuilderHere is an example defining a type-safe parameter builder:

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)};
  },
)

In this example, we GoRoutedefine a for paramsBuilder, which idconverts the argument from a string to an integer. This way, in pageBuilder, we can use type-safe idparameters directly.

5.3.5 Summary

This section describes how to go_routerpass parameters when navigating pages using , and receive those parameters in the target page. paramsYou can easily pass parameters between pages by adding dynamic parameters in the URL or by passing parameters when using named routes . At the same time, you can also define type-safe parameter builders using the attribute to avoid type errors when passing parameters GoRoute. paramsBuilderIn the next chapters, we will continue to explain go_routerhow to use the module in depth, including how to use route guards, handle page transition animations, and more.

6. Handling Deep Links and Redirects

6.1 The concept and application of deep link

Deep Linking is a technique that allows users to directly open specific pages within an app. Deep linking lets you navigate users from a web page, ad, email, or other app directly to a specific page of your app, not just the app's main page. This helps to improve user experience, increase user engagement, and improve app conversions.

In this section, we'll introduce the concept of deep linking and how to handle deep linking in a Fluttergo_router app using modules .

6.1.1 Types of deep links

There are two main types of deep links:

  1. Standard Deep Links : This type of deep link uses a standard URL format, eg https://example.com/details/123. When the user clicks on such a link, the app tries to open the corresponding page. If the app is not installed, the user will be redirected to the app store.
  2. Universal Links : Universal Links are a special type of deep linking that allow you to create a unique association for a URL. When a user clicks on a universal link, the system will automatically determine whether to open the app or webpage based on the associated information. Universal Links are called "Universal Links" and "App Links" on iOS and Android platforms, respectively.

6.1.2 Handling deep links in Flutter apps

To handle deep linking in your Flutteruni_links app, you need to use a library. First, pubspec.yamladd uni_linksthe library's dependencies in the file:

dependencies:
  uni_links: ^0.5.1

You then need to mainlisten for deep linking events at your app's entry point (usually a function). Here's an example of listening to deep link events:

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());
}

In this example, we use getUriLinksStreama function to get a stream of deep link events and listen to that stream to process deep links.

6.1.3 Handling deep links in go_router

To handle deep linking in a Fluttergo_router app using , you need to map the deep link's URL to a page within the app. Here's an example of handling deep links in :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';
    }
  },
);

In this example, we GoRouterdefine a redirectfunction that redirects the user to a page within the app based on the URL of the deep link.

6.1.4 Summary

This section introduces the concept of deep linking and how to handle deep linking in a Fluttergo_router app that uses modules . Deep linking is a technique that allows users to directly open a specific page within an app, which can help improve user experience, increase user engagement, and increase conversion rates for your app. In the next chapters, we will continue to explain how to handle redirection in , so as to better manage the page jump logic of the application.go_router

6.2 Using go_router to handle deep links

In the previous section, we introduced the concept of deep linking and how to handle deep linking in Flutter applications. This section focuses on how to go_routerhandle deep linking in apps using the module.

6.2.1 Install and configure the uni_links library

First, we need to install uni_linksthe library to handle deep linking. pubspec.yamlAdd uni_linksthe dependencies of the library in the file:

dependencies:
  uni_links: ^0.5.1

Next, we need to listen for deep linking events at the application's entry point (usually a mainfunction). Here's an example of listening to deep link events:

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());
}

6.2.2 Define the route of go_router

In order to handle deep linking, we need to go_routerdefine deep link related routes in . Here is an example with two routes defined:

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));
      },
    ),
  ],
);

In this example, we define two routes: home page ( /) and detail page ( /details/:id). The route for the detail page contains a idparameter named , which will be extracted from the URL of the deep link.

6.2.3 go_routerHandling deep links in

To go_routerhandle deep linking in , we need to define a redirectfunction. Here's an go_routerexample that handles deep linking in:

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';
    }
  },
);

In this example, we GoRouterdefine a redirectfunction that redirects the user to a page within the app based on the URL of the deep link.

go_router6.2.4 Using navigation in the application

Now that we've go_routerconfigured deep link handling, we can use the navigation functionality in our app go_router. Here's an go_routerexample of navigating to a details page:

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

In this example, we use GoRouter.ofa function to get GoRouteran instance of the app, and then call goa method to navigate to the details page.

6.2.5 Summary

This section describes how to handle deep linking in a Fluttergo_router app using the module . We first installed and configured the library, then defined the routes related to deep linking. Next, we define a function in to handle deep linking, and finally use in the app for navigation.uni_linksgo_routerredirectgo_router

By go_routerhandling deep linking with , you can provide a better experience for your users, resulting in higher user engagement and app conversions.

6.3 Implement redirection

In this section, we'll cover how to implement redirection in a Fluttergo_router app that uses modules . A redirect is a method of directing a user to another page when they try to access one. This is very useful in many scenarios, such as permission control, conditional rendering, etc.

6.3.1 Define redirection function

To implement redirection, we need to GoRouterdefine a redirectfunction in . Here's an example of a simple redirect function that /oldredirects a user from a path to /newa path:

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

In this example, we GoRouterdefine a redirectfunction for , which state.locationredirects the user to a different page depending on the value of .

6.3.2 Implement permission-based redirection

In practical applications, we may need to decide whether to allow access to a certain page according to the user's permissions. Here's an example of a permission-based redirection:

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

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

In this example, we first check if the user has access. If the user tries to access a protected page ( /protected), but does not have permission, we redirect the user to the login page ( /login). Among them checkUserPermission, the function is used to check whether the user has access rights. For example, if he is not logged in, he has no access rights. The following is the implementation code for reference:

bool checkUserPermission() {
    
    
  // 获取登录状态
  final SharedPreferences prefs = await SharedPreferences.getInstance();
  final isLoggedIn = prefs.getBool('is_logged_in') ?? false;

  // 如果未登录,则没有访问权限
  if (!isLoggedIn) {
    
    
    return false;
  }

  // 获取用户角色
  final userRole = prefs.getString('user_role') ?? '';

  // 针对具体情况判断用户是否有权访问受保护页面
  // 示例:只允许具有 'admin' 角色的用户访问
  if (userRole == 'admin') {
    
    
    return true;
  } else {
    
    
    return false;
  }
}

Among them, the user's login status and role can be obtained from the application's state manager, persistent storage, and other places. In the code, we use SharedPreferences as persistent storage, you can install the module shared_preferences:

flutter pub add shared_preferences

Then introduce in the code:

import 'package:shared_preferences/shared_preferences.dart';

To store data in SharedPreferences, you need to use getInstance() to obtain a SharedPreferences instance, and then use corresponding methods to store data, such as setBool(), setInt(), setString(), etc.:

Future<void> saveLoginStatus(bool isLoggedIn) async {
    
    
  final SharedPreferences prefs = await SharedPreferences.getInstance();
  prefs.setBool('is_logged_in', isLoggedIn);
}

To read data from SharedPreferences, you still need to obtain an instance first, and then use the corresponding methods for obtaining data, such as getBool(), getInt(), getString(), etc.:

Future<bool> getLoginStatus() async {
    
    
  final SharedPreferences prefs = await SharedPreferences.getInstance();
  final isLoggedIn = prefs.getBool('is_logged_in') ?? false;
  return isLoggedIn;
}

By default, the user is required to be an administrator role. In practice, more cases are stored in the background, and it is necessary to request back-end data to confirm user permissions. In this case, it is necessary to send a request to the backend API in the Flutter application, and then determine whether the user has the corresponding permissions based on the obtained data. The following is an example of using the http library (initiating a request to the backend) to obtain user permissions and execute the checkUserPermission function. You can install diomodule for Http requests:

flutter pub add dio

Then, import the dio library where the request needs to be sent:

import 'package:dio/dio.dart';

Then get the data from the backend to achieve checkUserPermission:

Future<bool> checkUserPermission() async {
    
    
  // 创建 Dio 实例
  Dio dio = Dio();

  try {
    
    
    // 向服务器发起请求获取用户权限数据,以下URL地址仅作示例,请根据您的实际API地址进行修改
    final response = await dio.get("https://your-server.com/api/user_permission");

    // 提取用户角色
    String userRole = response.data["role"];

    // 根据请求数据判断用户是否具有管理员权限
    if (userRole == "admin") {
    
    
      return true;
    } else {
    
    
      return false;
    }
  } catch (e) {
    
    
    // 如果请求失败,返回false表示没有访问权限
    return false;
  }
}

6.3.3 Implement condition-based redirection

In addition to permission-based redirection, we can also implement redirection based on other conditions. Here's an example of a condition-based redirect:

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

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

In this example, we first get the device type. If the user tries to visit the tablet-friendly page ( /tablet), but the device type is not a tablet, we redirect the user to the phone-friendly page ( /mobile).

6.3.4 Summary

This section describes how to implement redirection in a Fluttergo_router app that uses modules . We first defined a redirection function, and then introduced how to implement redirection based on permissions and conditions.

By implementing go_routerredirection, you can better manage your application's page transition logic, thereby improving user experience and application security. In the next chapters, we will continue to introduce go_routerother functions of the module, such as animated navigation and so on.

7. Route guard and route transition animation

7.1 The function and realization of route guard

In this section, we will introduce the concept of route guards and how to implement route guards in Fluttergo_router applications using modules . A route guard is an interceptor that is executed before a user tries to access a certain page, and can be used in scenarios such as permission control and data preloading.

7.1.1 The role of routing guards

The main functions of route guards are as follows:

  1. Permission Control: Before a user accesses a protected page, check whether the user has access permission. If you do not have permission, you can redirect to the login page or display a prompt message.
  2. Data preloading: Before the user visits a page, preload the required data. This can improve page load speed and improve user experience.
  3. Page jump control: Before the user visits a certain page, decide whether to allow page jump according to certain conditions.

7.1.2 Realize route guard

To go_routerimplement route guards in a module, we need to define a guardfunction for each route that needs to be guarded. Here is an example of a simple route 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],
    ),
    // ...其他路由定义...
  ],
);

In this example, we first define a authGuardroute guard function named . This function checks to see if the user has access, and if not, redirects to the login page and returns falseto prevent page jumps.

We then added attributes GoRouteto the protected page ( ) in the function with a guard./protectedguardsauthGuard

7.1.3 Summary

This section introduces the role of route guards and how to implement route guards in Fluttergo_router applications that use modules . A route guard is an interceptor that is executed before a user tries to access a certain page, and can be used in scenarios such as permission control and data preloading. By implementing route guards, you can better manage the page jump logic of your application, thereby improving user experience and application security.go_router

7.2 Use go_router to implement routing guards

In this section, we will discuss in depth how to go_routerimplement route guards using modules. We'll start with a simple permission control scenario, and then discuss how to implement more complex route guard functions.

7.2.1 Example: Permission Control

Suppose our application has two pages: a login page and a protected page. Users can only access protected pages after logging in. We can use go_routerthe routing guard function to achieve this requirement.

First, we need to define a route guard function for the protected page, as follows:

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

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

  return true;
}

Then, GoRouteadd an attribute for the protected page in guardswith authGuardthe function as a guard:

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

Now, the protected pages can only be accessed if the user is logged in. If the user is not logged in, they will be redirected to the login page.

7.2.2 Example: Data Preloading

In some cases, we may want to preload some data before the user visits the page. We can use route guards to achieve this functionality.

First, we need to define a routing guard function for loading data:

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

  return true;
}

Then, add properties GoRouteto the pages that need to preload data in , with functions as guards:guardsloadDataGuard

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

Now, before the user visits the data page, loadDataGuardthe function will be called to load the data.

7.2.3 Summary

This section discusses in depth how to go_routerimplement route guards using modules. We show how to implement permission control and data preloading through two examples. By go_routerimplementing route guards, you can better manage the page jump logic of your application, thereby improving user experience and application security.

8. go_router transition animation

In this chapter, we will discuss how to use the module to add custom transition animations go_routerfor the page transitions of a Flutter application. By default, Flutter provides some basic page transition effects, but sometimes we may need to customize these effects to improve user experience. By using go_routermodules, we can easily implement custom transition animations.

8.1 Example: Fade animation

We'll start by creating a simple fade transition animation. To do this, we need to use the component in the GoRouteprops . The following example demonstrates how to add a fade animation for page transitions:pageBuilderCustomTransitionPage

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(),
        );
      },
    ),
    // ...其他路由定义...
  ],
);

In this example, we've used CustomTransitionPagea component and transitionsBuilderset the property to a returned FadeTransitionfunction. This will give a fade effect when switching pages.

8.2 Example: Zoom animation

Next, we'll create a scaling transition animation. Similar to the previous example, we'll use CustomTransitionPagethe component and transitionsBuilderset the property to a returned ScaleTransitionfunction. The following example demonstrates how to add zoom animation for page switching:

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(),
        );
      },
    ),
    // ...其他路由定义...
  ],
);

In this example, we've used CustomTransitionPagea component and transitionsBuilderset the property to a returned ScaleTransitionfunction. This will give a zoom effect when switching pages.

8.3 Example: Combined animation

We can also combine multiple transition animations to create more complex effects. The following example demonstrates how to combine fade and scale animations:

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(),
        );
      },
    ),
    // ...其他路由定义...
  ],
);

In this example, we'll nest FadeTransitioncomponents ScaleTransitiontogether to apply a fade and scale effect at the same time.

8.4 Summary

This chapter describes how to use go_routermodules to add custom transition animations for the page transitions of a Flutter application. We've shown how to implement fade animations, scale animations, and composite animations with three examples. By using go_routermodules to implement custom route transition animations, you can improve user experience and add better visuals to your app.

F. Appendices

F.1 Flutter Route class API

F.1.1 Route<T> class constructor

Route({
    
    RouteSettings? settings})

Used to initialize Route. Among them, the RouteSettings class is data that may be useful for building a Route.

RouteSettings have the following properties:

Attributes type Label describe
arguments Object? final Parameters passed to this Route.
hashCode int read-only、inherited The hash code for this object.
name String? final The name of the Route (for example, "/settings").
runtimeType Type read-only、inherited A representation of the object's runtime type.

F.1.2 Route<T> class properties

Attributes type Label describe
currentResult T? read-only When popping this path (see Navigator.pop ), if no result is specified or the result is empty, this value will be used.
hasActiveRouteBelow bool read-only Whether there is at least one active route under this route.
hashCode int read-only、inherited the hash code for this object.
isActive bool read-only Whether this route is on the navigator.
isCurrent bool read-only Whether this route is the topmost (current) route on the navigator.
isFirst bool read-only Whether this route is the bottommost active route on the navigator.
navigator NavigatorState? read-only The navigator (if any) where the route is located.
overlayEntries List<OverlayEntry> read-only An override entry for this route.
popped Future<T?> read-only The Future completes when this route pops up from the navigator
restorationScopeId ValueListenable<String?> read-only The restoration scope ID to use for the RestorationScope around this route.
runtimeType Type read-only、inherited A representation of the object's runtime type.
settings RouteSettings read-only The settings for this route.
willHandlePopInternally bool read-only Whether calling didPop will return false.

F.1.3 Route<T> class methods

changedExternalState() → void

Called whenever the Navigator is updated in some way that may affect the route, to indicate that the route may also wish to rebuild.

changedInternalState() → void

Called whenever the internal state of the route changes.

didAdd() → void

Called after installing when a route has been added to the navigator .

didChangeNext(Route? nextRoute) → void

The next route for this route has changed to the given new route.

didChangePrevious(Route? previousRoute) → void

The previous route for this route has been changed to the given new route.

didComplete(T? result) → void

The route was popped or is being gracefully removed.

didPop(T? result) → bool

Pop the request for this route.

  • Return false if the route can handle it internally (e.g. because it has its own internal state stack);
  • Otherwise returns true (by returning the value of calling super.didPop). Returning false will prevent the default behavior of NavigatorState.pop.

didPopNext(Route nextRoute) → void

The given route above this route has been popped from the navigator.

didPush() → TickerFuture

Called after installation when a route is pushed to the navigator.

didReplace(Route? oldRoute) → void

Called after installation when a route in the navigator replaces another route.

dispose() → void

Any resources used by the object are discarded.

install() → void

Called when a route is inserted into the navigator.

willPop() → Future

Navigator.maybePopReturns whether calling should do anything when this Route is current .

F.2 Flutter Navigator class API

The navigator will Navigator.pagesconvert this to a routing stack (if provided). Navigator.pagesChanges in will trigger an update of the routing stack. The navigator will update its routes to match the new configuration of its Navigator.pages. To use this API, create a Page subclass and define a list of pages for Navigator.pages. Callback is also needed Navigator.onPopPageto properly clean up the input page when popping.

By default, the navigator will use the DefaultTransitionDelegate to decide how routes enter and exit the screen. To customize it, define a TransitionDelegate subclass, and provide it to Navigator.transitionDelegate.

See the Router widget for more information on using the pages API.

F.2.1 Navigator class properties

Attributes type Label describe
clipBehavior Clip final Depending on this option, the content will be clipped (or not).
hashCode int read-only, inherited the hash code for this object.
initialRoute String? final The name of the first route displayed.
key Key? final, inherited Controls how one Widget replaces another Widget in the tree.
observers List final A list of watchers for this Navigator.
onGenerateInitialRoutes RouteListFactory final When the Widget is created, if initialRoute is not null, this function is called to generate an initial list of Route objects.
onGenerateRoute RouteFactory? final Invoked when a route is generated for the given RouteSettings.
onPopPage PopPageCallback? final Called when pop is called, but the current route corresponds to a Page in the pages list.
onUnknownRoute RouteFactory? final Called when onGenerateRoute cannot generate a route.
pages List<Page> final A list of pages used to populate the history.
reportsRouteUpdateToEngine bool final Whether this Navigator should report route update messages to the engine when the topmost route changes.
requestFocus bool final Whether the Navigator and its topmost routes should request focus when a new route is pushed to the Navigator.
restorationScopeId String? final ID to restore the state of the Navigator, including its history.
routeTraversalEdgeBehavior TraversalEdgeBehavior final Controls focus transfer outside the first and last item of the focus range that defines focus traversal between Widgets inside a route.
runtimeType Type read-only, inherited The runtime type representation of the object.
transitionDelegate TransitionDelegate final The delegate used to decide how a route enters or leaves a screen during a page update.

F.2.2 Navigator class methods

method return type Label describe
createElement() StatefulElement inherited Create a StatefulElement to manage the widget's position in the tree.
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 该小部件的简短文本描述。

F.2.2 Navigator 类静态方法

方法 返回类型 描述
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 下方的现有路由。

F.3 go_router 模块的 GoRouter 类

【注意】: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。

Guess you like

Origin blog.csdn.net/qq_28550263/article/details/131376141
Recommended