This is the 16th day of my participation in the More text Challenge. For more details, see more text Challenge
In the last two articles we’ve looked at the use of Flutter’s native Navigator for page jumping, routing, and route interception.
- Implementation of App page routing and route interception
- Introduction and Practice (XV) : Routing parameter processing
Using native routing will do most of the work, but if you want to route a page like a browser URL, or control the transitions between pages, then native routing needs a lot of work. On pub, there is an excellent routing plugin called Fluro that addresses this type of problem.
How to use Fluro
The procedure for using Fluro is relatively simple, divided into the following three steps:
- build
FluroRouter
Route instance, one application can be one instance; - The handler that defines the routing path (
Handler
), used to match the processing method of different routing paths. - in
MaterialApp
In theonGenerateRoute
Set toFluroRouter.generator
Method to build a system route.
Note that by default, Fluro treats the path “/” as the root directory, so you must define a Handler for the root directory. In addition to routing does not exist, you can set the FluroRouter. NotFoundHandler routing handler definition errors.
Route Handler
Fluro’s key implementation is the Handler, which is defined as follows:
class Handler {
Handler({this.type = HandlerType.route, required this.handlerFunc});
final HandlerType type;
final HandlerFunc handlerFunc;
}
Copy the code
The constructor has two properties. One is the HandlerType enumeration, which has two values: route and function. The route used for routing is the route, which is the default value. HandlerFunc is mandatory; it is a method of response routing that returns a Widget in order to jump to the corresponding page.
typedef Widget? HandlerFunc(
BuildContext? context, Map<String.List<String>> parameters);
Copy the code
HandlerFunc receives the context context and carries routing parameters, which are a Map of routing parameters for the routing path. For example, /dynamic/: ID route. If the actual route is /dynamic/1? Event =a&event=b, then the format of parameters is as follows:
{
"id": ["1"]."event": ["a"."b"]}Copy the code
Note that the route parameters are all String data types. This Handler allows routing parameters to be passed to the child pages.
Use the sample
To manage routes uniformly, we define a class, RouterManager, whose properties are static members that can be accessed directly from the class without creating an example. Of course, considering encapsulation, you can also make it a singleton pattern. Note that FluroRouter can only be initialized once, otherwise it will result in a hot overload stating that the route has been defined. Let’s replace the route jump from the previous two articles with a Fluro jump. The RouterManager code looks like this:
/ / omit the import
class RouterManager {
static String splashPath = '/';
static String loginPath = '/login';
static String homePath = '/home';
static String dynamicPath = '/dynamic';
static String dynamicDetailPath = '$dynamicPath/:id';
static FluroRouter router;
static void initRouter() {
if (router == null) { router = FluroRouter(); defineRoutes(); }}static var loginHandler =
Handler(handlerFunc: (BuildContext context, Map<String.dynamic> params) {
return LoginPage();
});
static var dynamicDetailHandler =
Handler(handlerFunc: (BuildContext context, Map<String.dynamic> params) {
return DynamicDetailPage(params['id'] [0]);
});
static var splashHandler =
Handler(handlerFunc: (BuildContext context, Map<String.dynamic> params) {
return Splash();
});
static var homeHandler =
Handler(handlerFunc: (BuildContext context, Map<String.dynamic> params) {
return AppHomePage();
});
static var notFoundHandler =
Handler(handlerFunc: (BuildContext context, Map<String.dynamic> params) {
return NotFound();
});
static voiddefineRoutes() { router.define(splashPath, handler: splashHandler); router.define(homePath, handler: homeHandler); router.define(loginPath, handler: loginHandler); router.define(dynamicDetailPath, handler: dynamicDetailHandler); router.notFoundHandler = notFoundHandler; }}Copy the code
In practice, you only need to call the RouterManager. InitRouter method to complete the route initialization, which needs to be completed in the MaterialApp of main.dart. Compared to the previous code, you don’t need to set navigationKey parameters and initialRoute parameters. You just need to call the method that initializes the route in the build method.
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
RouterManager.initRouter();
return MaterialApp(
/ /...onGenerateRoute: RouterManager.router.generator, ); }}Copy the code
Page jump
Page jump call has many forms, this example we use three, respectively:
- Clear the routing stack jump: That is, the page after the jump as the root page (no back button), this is suitable for the splash screen page to jump to the home page. The code is as follows:
RouterManager.router.navigateTo(context, RouterManager.homePath, clearStack: true);
Copy the code
- Common jump: Direct jump without parameters. The code is as follows:
RouterManager.router.navigateTo(context, RouterManager.loginPath);
Copy the code
- Parameter jump: The route path takes parameters. It is similar to a normal jump except that it concatenates the path parameter and the query parameter:
RouterManager.router.navigateTo(context, '${RouterManager.dynamicPath}/$id? event=a&event=b')
Copy the code
Running effect
We skipped the splash screen page to the home page, dynamically skipped to the details page, and changed the login page and 404 page. The operation effect is as shown in the figure below. Notice the difference in the way the transition works. A normal transition pops from bottom to top, but 404 pops from left to right (just like the native push). This can then be tweaking in handlers or defining transitions when the route jumps, and we’ll see how this is used in the next article.