The route in a Flutter is similar to the route in React which usually refers to jumping from one page to another; In this case we call it the routing stack

There are three ways to route a FLUTTER: 👇🏻

Navigator.push

Navigator.push( context,
    MaterialPageRoute(builder: (context) {
        return Page1();
}));
Copy the code

This code uses two apis:

  • Navigator
  • MaterialPageRoute

Navigator

The first way is ✅

Navigator is a routing management component that provides methods to open and exit the routing page. The Navigator manages a collection of active routes through a stack. The current page is usually the route to the top of the stack. Navigator provides a number of ways to manage the routing stack, and we’ll cover only two of its most common methods here

  • Future push(BuildContext context, Route route)

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

  • bool pop(BuildContext context, [ result ])

The top of the stack is routed off the stack, and result is the data returned to the previous page when the page is closed.

There are many other methods for Navigator, such as navigator.replace, navigator.popuntil, etc. Please refer to the API documentation or SDK source notes for details. Next, we will introduce another routing concept, named routing.


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 component provided by the Material component library, which can realize the route switching animation consistent with the style of platform page switching animation for different platforms:

  • The ginseng
MaterialPageRoute({
    WidgetBuilder builder,
    RouteSettings settings,
    bool maintainState = true.bool fullscreenDialog = false,})Copy the code
  • 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).


RoutesMap

The second way is ✅

As the name implies, the routing table is registered directly in the MaterialApp similar to the way we Vue ‘React registers the routing table. We define a path for each route. This method is called named routing

MaterialApp(
  title: 'Flutter Demo',
  theme: ThemeData(
    primarySwatch: Colors.blue,
  ),
  // Register the routing table
  routes: {
    "/":(context) => MyHomePage(title: 'Flutter Demo Home Page'), // Register the home route
    'page1': (context) => Page1(),
    'page2': (context) => Page2()
  },
);

Copy the code
  • Opening mode:
onPressed: () {
  Navigator.pushNamed(context, "new_page");
  // Compare the previous method
  //Navigator.push(context,
  // MaterialPageRoute(builder: (context) {
  // return NewRoute();
  / /}));
},
Copy the code

onGenerateRoute

The third method ✅, which we call hook routing, is to execute a method to determine the meaning of something like an interceptor when performing a page jump

The MaterialApp has an onGenerateRoute property that may be called when the named route is opened. It is possible because Navigator. PushNamed (…) is called. When the named route is enabled, if the specified route name is registered in the routing table, the builder function in the routing table is called to generate routing components. If there is no registration in the routing table, onGenerateRoute is called to generate the route. The onGenerateRoute callback signature is as follows:

Route<dynamic> Function(RouteSettings settings)
Copy the code

A simple example is 🌰

 MaterialApp(
    / /... Omit irrelevant code

    onGenerateRoute: (RouteSettings settings) {
      String routeName = settings.name;
      print(settings);
      switch (routeName) {
        case '/':
          return MaterialPageRoute(builder: (context) {
            return MyHomePage(title: 'Flutter Demo Home Page');
          });

        case 'page1':
          return MaterialPageRoute(builder: (context) {
            return Page1(ps: settings.arguments);
          });
        case 'page2':
          return MaterialPageRoute(builder: (context) {
            return Page2(text: settings.arguments);
          });
        // Route mismatch By default, the home page is returned
        default:
          return MaterialPageRoute(builder: (context) {
            return MyHomePage(title: 'Flutter Demo Home Page'); }); }});Copy the code

With this method we have a lot of options, and of course we can do it in conjunction with RouteMap, because onGenerateRoute matches only if the path doesn’t match the routing table

The ginseng

With a route jump, of course, not upload 🤖

if

Using the first method, we can retrieve the passed parameters directly via ModalRoute

// Get route parameters
var  params = ModalRoute.of(context).settings.arguments as Map;
Copy the code

else

Otherwise, the named route can define the receive directly

For example, 🌰

class Page2 extends StatelessWidget {
  const Page2({Key key, this.text}) : super(key: key);
  final String text; // Define to receive the text argument

  @override
  Widget build(BuildContext context) {
    // Get route parameters
    var params = ModalRoute.of(context).settings.arguments;

    if (params == null) {
      // When the route parameter is empty, use the props parameter
      params = text;
    }

    return Scaffold(
      appBar: AppBar(
        title: Text("page2"),
      ),
      body: Center(
        child: Text('page2 Route parameters:$params'),),); }}Copy the code

summary

Using named routes is the most recommended of the above three methods because:

  1. clarity
  2. Centralized code for easy maintenance and management
  3. throughonGenerateRouteDo some interception

demo code

Complete code

main.dart

import "package:flutter/material.dart";

// Import the routing page
import './Page/Page1.dart';
import './Page/Page2.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
        title: 'Flutter Demo',
        initialRoute: '/',
        theme: new ThemeData(
          primarySwatch: Colors.blue,
        ),

        // Register the routing table
        // routes: {
        // "/" (context) => MyHomePage(title: 'Flutter HomePage '), // Register the homepage route
        // 'page1': (context) => Page1(),
        // 'page2': (context) => Page2()
        // },
        onGenerateRoute: (RouteSettings settings) {
          String routeName = settings.name;
          print(settings);
          switch (routeName) {
            case '/':
              return MaterialPageRoute(builder: (context) {
                return MyHomePage(title: 'Flutter Demo Home Page');
              });

            case 'page1':
              return MaterialPageRoute(builder: (context) {
                return Page1(ps: settings.arguments);
              });
            case 'page2':
              return MaterialPageRoute(builder: (context) {
                return Page2(text: settings.arguments);
              });
            // Route mismatch By default, the home page is returned
            default:
              return MaterialPageRoute(builder: (context) {
                return MyHomePage(title: 'Flutter Demo Home Page');
              });
          }

          // return MaterialPageRoute(builder: (context) {
          // return MyHomePage(title: 'Flutter Demo 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> {
  int _ct = 1;

  void addCt() {
    setState(() {
      _ct++;
    });
  }

  void reCt() {
    setState(() {
      _ct = 0;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text(
              'Here is the home page',),new Text(
              '$_ct',
              style: Theme
                  .of(context)
                  .textTheme
                  .headline4,
            ),
            ElevatedButton(onPressed: reCt, child: Text('reset')),
            ElevatedButton(
                onPressed: () {
                  Navigator.pushNamed(context, 'page1',
                      arguments: {'index': _ct, 'add': addCt});
                },
                child: Text('Open page 1')),
            ElevatedButton(
                onPressed: () {
                  Navigator.pushNamed(context, 'page2',
                      arguments: 'Pass parameters to page 2 hee Hee love');
                },
                child: Text('Open page 2'))
          ],
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: this.addCt,
        tooltip: 'Increment',
        child: newIcon(Icons.add), ), ); }}Copy the code

Page1.dart

import 'package:flutter/material.dart';

class Page1 extends StatelessWidget {
  const Page1({Key key, this.ps}) : super(key: key);
  final Map ps;

  @override
  Widget build(BuildContext context) {
    // Get route parameters
    var  params = ModalRoute.of(context).settings.arguments as Map;

    if (params == null) {
      params = ps;
    }

    return Scaffold(
      appBar: AppBar(
        title: Text("page1"),
      ),
      body: Center(
       child: new Column(
         children: [
           new Text(params['index'].toString()),
           new ElevatedButton(onPressed: (){
             params['add'] (); }, child: Text('Method of calling routing pass - added'() [(), (), (); }}Copy the code

Page2.dart

import 'package:flutter/material.dart';

class Page2 extends StatelessWidget {
  const Page2({Key key, this.text}) : super(key: key);
  final String text;

  @override
  Widget build(BuildContext context) {
    // Get route parameters
    var params = ModalRoute.of(context).settings.arguments;

    if (params == null) {
      // When the route parameter is empty, use the props parameter
      params = text;
    }

    return Scaffold(
      appBar: AppBar(
        title: Text("page2"),
      ),
      body: Center(
        child: Text('page2 Route parameters:$params'),),); }}Copy the code