Route in flutter is something that cannot be undone, must be confronted, and is often used

A Route is a Route that, as the name suggests, takes you between pages

There are no external dependencies, just note that the _rootRoute string needs to match initialRoute

Routes are classified into static and dynamic routes

Static routes do not need to be passed. Such routes can be defined directly in the MaterialApp/WidgetsApp and can be called via navigator.pushnamed

Dynamic is just passing in a PageRoute, usually a MaterialPageRoute or CupertinoPageRoute, or if you have a custom one you can use

Here I use a utility class of mine to implement the jump, because most of the routing in the project is dynamic, that is, requiring parameters to be passed, so the utility class contains only widget-related solutions

import 'dart:async';

import 'package:flutter/material.dart';

class RouteHelper {
  static Future<T> pushWidget<T>(
    BuildContext context,
    Widget widget, {
    bool replaceRoot = false.bool replaceCurrent = false, {})return pushRoute(
      context,
      MaterialPageRoute(builder: (ctx) => widget),
      replaceRoot: replaceRoot,
      replaceCurrent: replaceCurrent,
    );
  }

  static Future<T> pushRoute<T>(
    BuildContext context,
    PageRoute<T> route, {
    bool replaceRoot = false.bool replaceCurrent = false, {})assert(! (replaceRoot ==true && replaceCurrent == true));
    if (replaceRoot == true) {
      return Navigator.pushAndRemoveUntil(
        context,
        route,
        _rootRoute,
      );
    }
    if (replaceCurrent == true) {
      return Navigator.pushReplacement(context, route);
    }
    returnNavigator.push(context, route); }}var _rootRoute = ModalRoute.withName("home");
Copy the code

Parsing this class, there are two methods, one to accept PageRoute and one to receive Widget

The receiver of the Widget wraps it as the MaterialPageRoute and passes it to another method

The other method contains three cases, one is to replace the root node, one is to replace the current page (close the current page and open a new page), and another is the ordinary push(not close the current, directly open a new page).

It varies according to the different parameters

There is a _rootRoute variable that is intended to replace the root node. ‘home’ is the initialRoute I defined in the MaterialApp so that one-to-one correspondence ensures replacement of the root node


The class can also be extended by adding routes, passing the route name parameter, calling routes to extract the Widget/ route named, and passing the pushRoute method


Another benefit of this handy Helper is that it is easy to replace Route implementations in batches. For example, if you want to customize a PageRoute one day, instead of using the MaterialRoute, you just need to replace the parts shown below


Of course, there are other extensions to support named. For example, if you look at the Navigator source code and find pushNamed, you can get the route from the widget.onGenerateRoute method


Now that the Helper is done, let’s look at the method that we use and it’s really easy to use

For example, strong login apps

  void  _login() {
    RouteHelper.pushWidget(context, HomeRootPage(), replaceRoot: true);
  }
Copy the code

After a successful login, I directly replaced the root node, and the root route became the main page

  void _forgetPwd() {
    RouteHelper.pushWidget(context, ForgetPwdPage());
  }

  void _register() {
    RouteHelper.pushWidget(context, RegiseterPage());
  }
Copy the code

Forgetting passwords and registering are both done based on login, and eventually return to login, so use the normal call method here

  _register() {
    RouteHelper.pushWidget(
      context,
      RegisterSuccessPage(),
      replaceCurrent: true,); }Copy the code

After the successful registration, I have a separate registration success page with some notes after registration, and the return should be directly returned to the login page, so I need to replace the current page, just use replaceCurrent


Of course, methods that accept return values are also allowed

_orderDetail(String item) async {//todo view order details var result = await routehelper. pushWidget<bool>(context, OrderDetailPage(id: item));if (result == true) { _refresh(); }}Copy the code

Here, if you buy something on the details page/add it to the cart and go back to the main page, you refresh the page, so we receive the return value and decide

If (result==true) bool is true with 3 values. False null if(result==true The null case is avoided and code robustness is improved, a side effect of dart’s full object-oriented approach