- 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 模块的用法。
Table of contents
- 1 Overview
- 2. Flutter Routing Basics
- 3. Named routing and dynamic routing
- 4. Introduction to go_router module
- 5. Use go_router to realize page navigation
- 6. Handling Deep Links and Redirects
- 7. Route guard and route transition animation
- 8. go_router transition animation
- F. Appendices
-
- F.1 Flutter Route class API
-
- F.1.1 Route\<T> class constructor
- F.1.2 Route\ class properties
- F.1.3 Route\<T> class methods
-
- changedExternalState() → void
- changedInternalState() → void
- didAdd() → void
- didChangeNext(Route? nextRoute) → void
- didChangePrevious(Route? previousRoute) → void
- didComplete(T? result) → void
- didPop(T? result) → bool
- didPopNext(Route nextRoute) → void
- didPush() → TickerFuture
- didReplace(Route? oldRoute) → void
- dispose() → void
- install() → void
- willPop() → Future<RoutePopDisposition>
- F.2 Flutter Navigator class API
- F.3 The GoRouter class of the go_router module
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_router
Introduction to modules, including installation, configuration, definition and registration of routes, etc.;- Use to
go_router
implement 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_router
build 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 PageRoute
class that inherits from .
PageRoute
Is an abstract class that represents a Navigator
page 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: MaterialPageRoute
or 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.push
methods 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:
- An object defining a new page
Route
, such asMaterialPageRoute
orCupertinoPageRoute
. - Use
Navigator.push
the 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.push
the method, we can realize the function of jumping from the current page to the new page. In actual development, we usually use MaterialPageRoute
or CupertinoPageRoute
to 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.pop
the 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:
- Use
Navigator.pop
the method to return to the previous page.
// 使用Navigator.pop方法返回上一个页面
Navigator.of(context).pop();
Through Navigator.pop
the method, we can realize the function of returning from the current page to the previous page. In actual development, we usually call Navigator.pop
the 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 Route
pass 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.push
through 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 MaterialApp
or .CupertinoApp
routes
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.pushNamed
the 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.popAndPushNamed
the 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.pushReplacementNamed
methods 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 MaterialApp
or CupertinoApp
properties .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.pushNamed
the 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.popAndPushNamed
the 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.pushReplacementNamed
methods 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:
- Definition method : Named routes are defined through
MaterialApp
orCupertinoApp
attributesroutes
, while dynamic routesonGenerateRoute
are defined through attributes. - Parameter passing : When a named route performs page jumps, parameters need to be defined in the route name, while dynamic routes can
arguments
directly pass parameters through attributes. - 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.
- 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:
- 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.
- 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_router
the advantages and features of the module. go_router
is a routing library for Flutter , which provides a simple, powerful and easy-to-maintain routing management method.
The solution go_router
module has the following advantages:
- Type safety :
go_router
The module supports type-safe routing parameter passing, which can effectively reduce runtime errors caused by wrong parameter types. - Concise code :
go_router
The module adopts declarative programming method, which can make your code more concise, easy to read and easy to maintain. - Rich functions :
go_router
The 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. - Compatible with existing frameworks :
go_router
The 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_router
the module has the following characteristics:
- Named routing :
go_router
The module supports named routing, which allows you to manage and jump to specified pages more conveniently. - Dynamic routing :
go_router
The 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. - Routing guard :
go_router
The module supports routing guards, which can add conditional judgments during the routing jump process, such as identity verification, permission checks, etc. - Route redirection :
go_router
The module supports route redirection, which can redirect users from one route to another as needed. - Browser Support :
go_router
The 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_router
the module. Through the following steps, you can go_router
add the module to your Flutter project and perform basic configuration.
4.2.1 Add dependencies
First, in your Flutter project's pubspec.yaml
files, add go_router
the module's dependencies. You can find the latest version of the module on pub.dev . go_router
Here is an example of adding dependencies:
dependencies:
flutter:
sdk: flutter
go_router: ^2.4.2
After adding dependencies, run flutter pub get
the command to download and install go_router
the module.
4.2.2 Import go_router module
In the file that needs to use go_router
the module, import go_router
the 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 GoRoute
list of objects, each GoRoute
representing 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 GoRouter
object and pass it the list of previously defined routes:
final goRouter = GoRouter(routes: goRoutes);
4.2.5 Configuring MaterialApp or CupertinoApp
Pass GoRouter
the object to MaterialApp.router
or CupertinoApp.router
property. Here is an MaterialApp
example configuration:
MaterialApp.router(
routerDelegate: goRouter.routerDelegate,
routeInformationParser: goRouter.routeInformationParser,
);
4.2.6 Summary
This section describes how to install and configure go_router
the module. You can integrate go_router
modules 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_router
how 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_router
routes 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 GoRoute
list of objects to define routes. Each GoRoute
object 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 (egMaterialPage
,CupertinoPage
etc).
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 GoRouter
object and pass it the route list. This way, your routes will be registered in go_router
the 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 name
attribute 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 GoRouter
the object's goNamed
methods 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_router
routes in the module. By creating GoRoute
a 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 GoRouter
in your Flutter project. go_router
In the next chapters, we will continue to explain go_router
how 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_router
implement 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_router
Page jumping using modules is very simple. You simply call GoRouter
the object's go
method, passing in the current BuildContext
and target page URLs. The following is an example of a page jump:
goRouter.go(context, '/details/123');
In this example, we jump to /details/123
the page corresponding to the path.
5.1.2 Passing parameters
go_router
Modules 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 GoRouterState
of the object . params
Here 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 GoRouter
the object's goNamed
method to jump to the specified page and pass parameters:
goRouter.goNamed(context, 'details', params: {
'id': '123'});
In this example, we jump to details
the page corresponding to the route named and pass a id
parameter.
5.1.4 Summary
This section describes how to go_router
implement URL-based page navigation using the module. By calling GoRouter
the object's go
or method, you can easily perform page jumps and parameter passing in goNamed
your Flutter project. In the next chapters, we will continue to explain in depth go_router
how 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 GoRouter
the methods provided by the class for page navigation. GoRouter
The 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
GoRouter
The methods of the class go
allow you to navigate pages by URL. You simply pass in the current BuildContext
and target page URLs. The following is an go
example of using the method to jump to the page:
goRouter.go(context, '/details/123');
In this example, we jump to /details/123
the page corresponding to the path.
5.2.2 Navigating using the goNamed method
GoRouter
The methods of the class goNamed
allow 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 goNamed
example of using the method to jump to the page:
goRouter.goNamed(context, 'details', params: {
'id': '123'});
In this example, we jump to details
the page corresponding to the route named and pass a id
parameter.
5.2.3 Use the goBack method to return to the previous page
GoRouter
The methods of the class goBack
allow you to go back to the previous page. You just pass in the current BuildContext
one. Here's an goBack
example 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
GoRouter
The methods of the class goTo
allow you to jump to a specified page. You need to pass in the current BuildContext
, an GoRouteMatch
object, and an optional parameter map. The following is an example of using goTo
the 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 match
the method to obtain the object corresponding to the URL GoRouteMatch
, and then use goTo
the method to jump to the specified page and pass a id
parameter.
5.2.5 Summary
This section describes how to use GoRouter
classes for page navigation. By calling the , , and methods GoRouter
of 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.go
goNamed
goBack
goTo
go_router
5.3 Passing between pages to participate in receiving parameters
When go_router
navigating through pages with , you may need to pass parameters between pages. This section will introduce how to go_router
pass 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 params
pass 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 123
pass as a parameter /details/123
the 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 details
the page, params
passing a id
parameter 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 pageBuilder
in the method . Here is an example of receiving parameters on the target page:GoRouterState
params
final id = state.params['id'];
In this example, state.params
we get id
the 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
. paramsBuilder
Here 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 GoRoute
define a for paramsBuilder
, which id
converts the argument from a string to an integer. This way, in pageBuilder
, we can use type-safe id
parameters directly.
5.3.5 Summary
This section describes how to go_router
pass parameters when navigating pages using , and receive those parameters in the target page. params
You 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
. paramsBuilder
In the next chapters, we will continue to explain go_router
how 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:
- 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. - 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.yaml
add uni_links
the library's dependencies in the file:
dependencies:
uni_links: ^0.5.1
You then need to main
listen 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 getUriLinksStream
a 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 GoRouter
define a redirect
function 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_router
handle deep linking in apps using the module.
6.2.1 Install and configure the uni_links library
First, we need to install uni_links
the library to handle deep linking. pubspec.yaml
Add uni_links
the 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 main
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());
}
6.2.2 Define the route of go_router
In order to handle deep linking, we need to go_router
define 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 id
parameter named , which will be extracted from the URL of the deep link.
6.2.3 go_router
Handling deep links in
To go_router
handle deep linking in , we need to define a redirect
function. Here's an go_router
example 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 GoRouter
define a redirect
function that redirects the user to a page within the app based on the URL of the deep link.
go_router
6.2.4 Using navigation in the application
Now that we've go_router
configured deep link handling, we can use the navigation functionality in our app go_router
. Here's an go_router
example 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.of
a function to get GoRouter
an instance of the app, and then call go
a 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_links
go_router
redirect
go_router
By go_router
handling 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 GoRouter
define a redirect
function in . Here's an example of a simple redirect function that /old
redirects a user from a path to /new
a path:
final goRouter = GoRouter(
routes: [
// ...路由定义...
],
redirect: (state) {
if (state.location == '/old') {
return '/new';
}
},
);
In this example, we GoRouter
define a redirect
function for , which state.location
redirects 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 dio
module 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_router
redirection, 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_router
other 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:
- 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.
- Data preloading: Before the user visits a page, preload the required data. This can improve page load speed and improve user experience.
- 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_router
implement route guards in a module, we need to define a guard
function 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 authGuard
route guard function named . This function checks to see if the user has access, and if not, redirects to the login page and returns false
to prevent page jumps.
We then added attributes GoRoute
to the protected page ( ) in the function with a guard./protected
guards
authGuard
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_router
implement 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_router
the 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, GoRoute
add an attribute for the protected page in guards
with authGuard
the 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 GoRoute
to the pages that need to preload data in , with functions as guards:guards
loadDataGuard
final goRouter = GoRouter(
routes: [
GoRoute(
path: '/data',
pageBuilder: (context, state) {
return MaterialPage(child: DataPage());
},
guards: [loadDataGuard],
),
// ...其他路由定义...
],
);
Now, before the user visits the data page, loadDataGuard
the function will be called to load the data.
7.2.3 Summary
This section discusses in depth how to go_router
implement route guards using modules. We show how to implement permission control and data preloading through two examples. By go_router
implementing 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_router
for 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_router
modules, 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 GoRoute
props . The following example demonstrates how to add a fade animation for page transitions:pageBuilder
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(),
);
},
),
// ...其他路由定义...
],
);
In this example, we've used CustomTransitionPage
a component and transitionsBuilder
set the property to a returned FadeTransition
function. 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 CustomTransitionPage
the component and transitionsBuilder
set the property to a returned ScaleTransition
function. 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 CustomTransitionPage
a component and transitionsBuilder
set the property to a returned ScaleTransition
function. 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 FadeTransition
components ScaleTransition
together to apply a fade and scale effect at the same time.
8.4 Summary
This chapter describes how to use go_router
modules 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_router
modules 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.maybePop
Returns whether calling should do anything when this Route is current .
F.2 Flutter Navigator class API
The navigator will Navigator.pages
convert this to a routing stack (if provided). Navigator.pages
Changes 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.onPopPage
to 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 是两个类。
- GoRouter 类是 go_router 的核心类,负责管理整个应用程序的路由系统。它维护了一个路由配置(RouteConfiguration),管理路由信息的解析(GoRouteInformationParser)和提供(GoRouteInformationProvider),以及控制页面导航和路由状态的变化。GoRouter 类提供了一系列方法来处理路由的导航、添加监听器、刷新路由等操作,如 push、pop、replace、addListener、refresh 等。
- 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。 |