This is the 12th day of my participation in the More text Challenge. For details, see more text Challenge
Why use routing
In our previous code, the page jump uses the following code:
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 drawbacks:
- Code is heavily coupled: where a page jump is involved, the page constructor needs to be inserted, which means you need to know how other pages are built.
- Easy to maintain: Once a page changes, all hops to that page need to change.
- Inconvenient permission control: Assume that some pages need to be authorized to access, and you need to insert permission judgment in various places.
Introduction to Flutter Route
First of all, this route introduction is the implementation of Flutter 1.0. Flutter 2.0 is a big change in routing, using declarative refactoring of routing, which is more complex to use. The Route configuration parameters are provided in the MaterialApp of the Flutter. When using the route configuration, the construction form of the MaterialApp is as follows:
return MaterialApp(
// Other parameters...
navigatorKey: // Global navigation state Key,
onGenerateRoute: // Route change response method,
initialRoute: // Initialize the routing path,
);
Copy the code
navigatorKey
Is aGlobalKey<NavigatorState>
Object for the state of the global storage navigation.onGenerateRoute
Is a route interceptor, which is called when the route changes, so that different pages can be returned depending on the route parameters, or route interception can be performed.initialRoute
To initialize the route path, which is usually the path of the startup page or home page.
Page structure and logic
To demonstrate the use of routing, we used four pages:
AppHomePage
: Home page, same as the page frame of the previous chapter, routing path is “/”;Splash
: Launch page, only one image, actual use process can be used to load the boot page, advertising or other purposes. Stay on the page for 2 seconds and switch to the home page.LoginPage
: Login page, used to demonstrate the route switch to the login page by clicking the login button.NotFound
: indicates the 404 page. If there is no matching path in the routing table, the route is forwarded to the 404 page.
Here the route jump is divided into two types, one is from the start page to the home page, this jump can not return; The second is the normal adjustment, you can click the back button to return to the upper level. The Flutter provides different ways to deal with these two conditions.
Implement key code
The first is the implementation of routing tables and route interception responses. Create a router_table.dart file in the router_table.dart folder and the code is 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 pages
notFoundPath: (context) => NotFound(),
/ / start page
splashPath: (context) => Splash(),
/ / login
loginPath: (context) => LoginPage(),
/ / home page
homePath: (context) => AppHomePage(),
};
///Routing to intercept
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);
returnwidget; }); }}Copy the code
Static properties and static methods are all used here so that the properties and methods can be accessed directly from the class name without having to build the object over and over again. In this way, route access can also be accessed directly through the static property of the class name, avoiding spelling errors. With this class, all pages of your App can be managed centrally through this class, thus avoiding multiple maintenance.
The key here is the onGenerateRoute method, which receives a RouteSettings object with a name attribute containing the route path name and arguments to carry route parameters. This property can be used to match pages in the routing table. If a match is found, the corresponding page is returned. If no match is found, the server is routed to the 404 page. At the same time, if you need to do permission control, you can also intercept here, such as locating the 403 page or directly reminding you of no access rights.
The next step is to modify the main.dart file to use the corresponding reason configuration when building the 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) {
returnMaterialApp( navigatorKey: navigationKey, onGenerateRoute: RouterTable.onGenerateRoute, initialRoute: RouterTable.splashPath, ); }}Copy the code
You can see here that in Main. dart we don’t need to import the relevant page by import, but we can directly configure the configuration properties of the route.
Page Routing
The navigation State in Flutter provides pushNamed and pushReplacementNamed methods. The former has a back button in the navigation bar. The latter uses the routed page to replace the current page directly. Adjustments for the launch page. Stay in the launch page for a few seconds in the future, use a timer, and jump after 2 seconds, can actually be used to do some preloaded resource hint or advertising display.
@override
void didChangeDependencies() {
super.didChangeDependencies();
if(! _initialized) { _initialized =true;
Timer(const Duration(milliseconds: 2000), () { Navigator.of(context).pushReplacementNamed(RouterTable.homePath); }); }}Copy the code
Normal pages jump directly using pushNamed, to return to the upper level, use the pop method. Both push and POP methods can carry parameters, and we will see how to handle routing parameters in the next article. Here we purposely added an incorrect route to demonstrate the 404 jump:
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ButtonUtil.primaryTextButton('login', () {
Navigator.of(context).pushNamed(RouterTable.loginPath);
}, context),
SizedBox(
height: 10,
),
ButtonUtil.primaryTextButton('404', () {
Navigator.of(context).pushNamed('errorRoute');
}, context),
],
),
),
Copy the code
The final running effect is shown in the figure below.