Route
The so-called route management is to manage how to jump between pages, also known as navigation management. Similar to native development, navigation is managed by maintaining a routing stack on both Android and iOS, where a push operation opens a new page and a pop operation closes the page. In Flutter development, both Route and Navigator are required for page hopping.
- A Route is an application abstraction of a screen or page;
- The Navigator is a widget that manages routes;
Route is usually used to represent the Page of a mobile application in mobile development. Specifically, Route refers to an Activity in Android and a ViewController in iOS.
Navigator is a routing widget that manages a collection of routing widgets through a stack. Usually the page displayed on the current screen is the route to the top of the stack, and Navigator provides a number of methods to manage the routing stack.
The sample
Dart to illustrate how Flutter can redirect, we create two pages: newroute.dart and main.dart. Dart newroute.dart newroute.dart
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('New page')
),
body: new Center(
child: new Text(
'Click the float button to return to home page', ), ), floatingActionButton: new FloatingActionButton( onPressed: () { Navigator.of(context).pop(); }, child: new Icon(Icons.replay), ), ); }}Copy the code
The new route is inherited from the StatelessWidget and has a simple interface that displays “This is new Route “in the middle of the page. Then, modify the main.dart source code as follows:
import 'package:flutter/material.dart';
import 'package:flutter_demo/SecondPage.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Route Management Home page')); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => new _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { @override Widget build(BuildContext context) {return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Text(
'Click the float button to open a new page', ), ), floatingActionButton: new FloatingActionButton( onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (context) => SecondPage())); }, child: new Icon(Icons.open_in_new), ), ); }}Copy the code
Running the code above, when we click the button, routing will open a new routing page, as shown below:
MaterialPageRoute
The MaterialPageRoute is derived from the PageRoute class, which is an abstract class that represents a modal routing page occupying the entire screen space. It also defines the interface and properties of the transition animation during route construction and switching. MaterialPageRoute is a Widget of the Material component library, which can implement the route switching animation with the same style of platform page switching animation for different platforms, specifically:
- For Android, when a new page is opened, the new page slides from the bottom of the screen to the top of the screen; When you close a page, the current page slides from the top of the screen to the bottom of the screen and disappears, while the previous page is displayed.
- For iOS, when a page is opened, a new page slides from the right edge of the screen to the left until the new page is fully displayed, while the previous page slides from the current screen to the left and disappears. When you close a page, the reverse happens: the current page slides out from the right side of the screen, while the previous page slides in from the left.
When we use the MaterialPageRoute constructor to complete the route jump, the MaterialPageRoute constructor provides several parameters in the format as follows:
MaterialPageRoute({
WidgetBuilder builder,
RouteSettings settings,
bool maintainState = true,
bool fullscreenDialog = false,})Copy the code
The meanings of these parameters are as follows:
- Builder is a callback function of type WidgetBuilder that builds the details of the routing page and returns a widget. We typically implement this callback to return an instance of the new route.
- The Settings contains the configuration information of the route, such as the route name and whether the route is an initial route (home page).
- MaintainState: By default, when a new route is pushed, the original route is still saved in memory. To release all the resources used by the route, you can set maintainState to false.
- FullscreenDialog indicates whether the new routing page is a full-screen modal dialog. In iOS, if fullscreenDialog is true, the new page will slide in from the bottom of the screen (rather than horizontally).
Navigator
Navigator is a route management widget in Flutter application development that manages a collection of route widgets via a stack. Typically, the page displayed on the current screen is the route to the top of the stack. Navigator provides a number of methods to manage the routing stack, and you can use push and POP to push and pop pages.
push
When the given route is pushed onto the stack (that is, a new page is opened), the return value is a Future object to receive the data returned when the new route is pushed off the stack (that is, closed).
When we perform the push operation, we mainly use two methods: one is to push a route directly, and the other is to pushNamed a named routing address.
Push way
The Route object has a RouteSettings member variable, which we can pass into the RouteSettings when constructing the Route object.
@optionalTypeArgs
static Future<T> push<T extends Object>(BuildContext context, Route<T> route) {
return Navigator.of(context).push(route);
}
Copy the code
If passing parameters is involved, we can place them in the constructor of SecondScreen, or in the RouteSettings of the MaterialPageRoute construct.
Navigator.push(Context, new MaterialPageRoute(Builder: (context) => new SecondScreen()),).then((data){// Accept the returned argumentsprint(data.toString());
};
Copy the code
PushNamed way
The pushNamed method finally calls the push method, which directly exposes the Object arguments.
@optionalTypeArgs
static Future<T> pushNamed<T extends Object>(
BuildContext context,
String routeName, {
Object arguments,
}) {
return Navigator.of(context).pushNamed<T>(routeName, arguments: arguments);
}
@optionalTypeArgs
Future<T> pushNamed<T extends Object>(
String routeName, {
Object arguments,
}) {
return push<T>(_routeNamed<T>(routeName, arguments: arguments));
}
Copy the code
When pushNamed is used, routes need to be registered in the routing table. For example:
Navigator.of(context)
.pushNamed(
'/route1',
arguments: {
"name": 'hello'}).then((data){// accept the returned argumentsprint(data.toString());
};
Copy the code
pop
The pop operation routes the top of the stack out of the stack, taking in an object of type and out the data returned to the previous page when the current page is closed.
Pop source code is as follows:
@optionalTypeArgs
static bool pop<T extends Object>(BuildContext context, [ T result ]) {
return Navigator.of(context).pop<T>(result);
}
Copy the code
The use of pop is very simple, for example:
Navigator.of(context).pop(""); // Arguments can be passedCopy the code
To jump between two pages, if it involves passing parameters, you can use the following method:
Navigator.of(context).pushNamed('/route1', arguments: {"name": 'hello'});
Copy the code
To get parameters, use the following methods:
class Page extends StatelessWidget{
String name;
@override
Widget build(BuildContext context) {
dynamic obj = ModalRoute.of(context).settings.arguments;
if(obj ! = null && isNotEmpty(obj["name"])) {
name = obj["name"];
}
return Material(
child: Center(
child: Text("this page name is ${name}"),),); }}Copy the code
After routing
A named route is a route with a name. You can open a new route using the name of the route. This provides an intuitive and simple way to manage routes, which is very similar to the Path defined by the ARrouter page jump framework in Android.
The route names conventionally use a path-like structure, with the application’s home page route defaulting to ‘/ ‘, for example, ‘/ home’ for HomeScreen and ‘/ login’ for LoginScreen.
The routing table
To use named routing, we must first provide and register a routing table so that the application knows which name corresponds to which routing Widget. The routing table is defined as follows:
Map<String, WidgetBuilder> routes;
Copy the code
It is a Map. Key is the name of the route and is a string. Value is a Builder callback function that generates the corresponding routing Widget. When we push a new route by route name, the application will find the corresponding WidgetBuilder callback function in the routing table based on the route name, and then call this callback function to generate the routing widget and return it.
For example, we create the MaterialApp with a routes constructor parameter:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
home: new MyHomePage(title: 'Application Home page'),
routes: <String, WidgetBuilder> {
'/a': (BuildContext context) => new MyPage(title: 'A page'),
'/b': (BuildContext context) => new MyPage(title: 'B page'),
'/c': (BuildContext context) => new MyPage(title: 'C page')}); }}Copy the code
Register routing table
The route registration method for Flutter is simple. Go back to the previous example of the “counter” and add the routes attribute to the MaterialApp build method of the MyApp class.
return new MaterialApp(
title: 'Flutter Demo', theme: new ThemeData(primarySwatch: color.blue,), // registered routing table :{"new_page":(context)=>NewRoute(),
} ,
home: new MyHomePage(title: 'Flutter Demo Home Page'));Copy the code
This completes the routing table registration using routes. Now we can open the new route by route name. The format of the pushNamed jump is as follows:
Future pushNamed(BuildContext context, String routeName,{Object arguments})
Copy the code
In addition to the pushNamed method, Navigator also has other methods such as pushReplacementNamed to manage named routes. You can check the API documentation for yourself. Next we open the new routing page using the route name and modify the FlatButton onPressed callback code:
onPressed: () {
Navigator.pushNamed(context, "new_page");
//Navigator.push(context,
// new MaterialPageRoute(builder: (context) {
// returnnew NewRoute(); / /})); },Copy the code
Named route parameter transmission
In the original version of Flutter, named routes could not pass parameters, but parameters were later supported. For example, the following shows how named routes are passed and get route parameters. First, register a route:
routes:{
"new_page":(context)=>EchoRoute(),
} ,
Copy the code
The routing parameters are then obtained via the RouteSetting object on the routing page, for example:
Class EchoRoute extends StatelessWidget {@override Widget Build (BuildContext context) {// Get the route parameter var args=ModalRoute.of(context).settings.arguments //... Omit extraneous code}}Copy the code
Then, pass the argument when opening the route:
Navigator.of(context).pushNamed("new_page", arguments: "hi");
Copy the code