why use routing

in our previous code, the code used for page jumps looks like this:

 Navigator.of(context).push(  MaterialPageRoute(builder: (context) => LoginPage()),);

copy the code

during the development process, as the number of pages increases, if you continue to use this method, there will be the following defects:

  • code coupling is severe: where page jumps are involved, you need to insert the page’s constructor, which means you need to know how other pages are being built.
  • not easy to maintain: once a page has changed, you need to change all the jumps involved in that page.
  • inconvenient permission control: assuming that some pages need to be authorized before they can be accessed, permission judgments need to be inserted everywhere.

Introduction to Flutter routing

First of all, the routing introduction of this article is the implementation of Flutter 1.0, Flutter 2.0 has made great changes to the routing, using a declarative way to reconstruct the route, which will be more complicated to use. The MaterialApp in Flutter provides route configuration parameters, and when configured with routes, the MaterialApp is constructed as follows:

return MaterialApp(  //其他参数...  navigatorKey: //全局导航状态Key,  onGenerateRoute: //路由改变响应方法,  initialRoute: //初始化路由路径,);

copy the code

  • navigatorKeyis an object that is used to globally store the state of navigation.GlobalKey<NavigatorState>
  • onGenerateRouteas a route interceptor, the method is called when the route changes, so that different pages can be returned according to the route parameters, or route interception can be performed.
  • initialRouteto initialize the routing path, it is usually the path of the startup page or the first page.

page structure and logic

to demonstrate the use of routing, we used four pages:

  • AppHomePage : home page, like the page frame of the previous chapter, the routing path is “/”;
  • Splash: start page, only one image, the actual use process can be used to load the boot page, advertising or other purposes. the page stays for 2 seconds and then switches to the home page.
  • LoginPage: login page that demonstrates clicking the login button to switch to the login page via routing.
  • NotFound: that is, the 404 page, jumps to the 404 page when there is no matching path in the routing table.

There are two types of route jumps here, one is to jump from the start page to the home page, which is not returnable, and the other is the normal adjustment, you can click the back button to return to the previous level. Different approaches are available in Flutter to deal with both situations.

implement the key code

the first is the implementation of the route table and the route interception response, and create a new router_table.dart file in the routers folder, as follows:

import 'package:flutter/cupertino.dart';import 'package:flutter/material.dart';import '../app.dart';import '../login.dart';import '../not_found.dart';import '../splash.dart';
class RouterTable { static String splashPath = 'splash'; static String loginPath = 'login'; static String homePath = '/'; static String notFoundPath = '404';
static Map<String, WidgetBuilder> routeTables = { //404页面 notFoundPath: (context) => NotFound(), //启动页 splashPath: (context) => Splash(), //登录 loginPath: (context) => LoginPage(), //首页 homePath: (context) => AppHomePage(), };
///路由拦截 static Route onGenerateRoute<T extends Object>(RouteSettings settings) { return CupertinoPageRoute<T>( settings: settings, builder: (context) { String name = settings.name; if (routeTables[name] == null) { name = notFoundPath; }
Widget widget = routeTables[name](context);
return widget; }, ); }}

copy the code

Static properties and static methods are used here in order to access properties and methods directly from the class name without having to repeatedly construct the object. In this way, the route can also be directly accessed through the static property of the class name, which can avoid spelling errors. With this class, all pages of the app can be centrally managed through this class, thus avoiding multiple maintenance.

the key here is the method, which receives an object that has an attribute that contains the routing path name and a route parameter that carries the routing parameters. this attribute allows you to match the pages of the route table. if there is a match, the corresponding page is returned, and if there is no match, it is routed to the 404 page. at the same time, if you need to do permission control, you can also intercept it here, such as targeting to the 403 page or directly reminding that there is no access.onGenerateRouteRouteSettingsnamearguments

The next step is to transform the main.dart file to use the corresponding rationale configuration when building MaterialApp:

import 'package:flutter/material.dart';import 'routers/router_table.dart';
void main() { runApp(MyApp());}
class MyApp extends StatelessWidget { final GlobalKey navigationKey = GlobalKey<NavigatorState>();
@override Widget build(BuildContext context) { return MaterialApp( navigatorKey: navigationKey, onGenerateRoute: RouterTable.onGenerateRoute, initialRoute: RouterTable.splashPath, ); }}

copy the code

here we will find that in main.dart we no longer need to import the relevant pages, but can directly configure the configuration properties of the route.

page route jumps

Page route jumping is more convenient, in Flutter provides a pushNamed method, the former will have a back button in the navigation bar, the latter is to use the routed page directly replace the current page, suitable for the adjustment of the start page. Staying in the splash page for a few seconds in the future, using a timer, and then jumping after 2 seconds, can actually be used to make some preloaded asset hints or ad impressions.NavigatorStatepushReplacementNamed

@overridevoid didChangeDependencies() {  super.didChangeDependencies();  if (!_initialized) {    _initialized = true;    Timer(const Duration(milliseconds: 2000), () {      Navigator.of(context).pushReplacementNamed(RouterTable.homePath);    });  }}

copy the code

jumps to normal pages can be used directly, or methods are used to return to the previous level. and methods can carry parameters, and in the next article we will introduce how to deal with route parameters. here we deliberately added a bad route to demonstrate a 404 jump:pushNamedpoppushpop

body: Center(  child: Column(    mainAxisAlignment: MainAxisAlignment.center,    children: [      ButtonUtil.primaryTextButton('登录', () {        Navigator.of(context).pushNamed(RouterTable.loginPath);      }, context),      SizedBox(        height: 10,      ),      ButtonUtil.primaryTextButton('404', () {        Navigator.of(context).pushNamed('errorRoute');      }, context),    ],  ),),

copy the code

the final operation effect is shown in the following figure.