previous Flutter routing and route interception jump 404 | Summer (welike.press) describes the use of routes to implement jumping of pages, thereby simplifying coupling between pages, and enabling route interception. in actual development, we often need to carry route parameters when the page jumps, a typical example is that when we go from the list to the detail page, we need to carry the id of the detail so that the detail page can get the corresponding data. at the same time, sometimes it is necessary to return with parameters to return to the previous level, so that the parent page can be updated according to the returned results. this article describes the implementation of both scenarios.

Navigator’s push and pop methods

Navigator the navigator’s and methods can carry parameters between pages, as can other morphing methods. the method prototype is as follows:pushpoppushNamed

Future<T?> pushNamed<T extends Object?>(  String routeName, {  Object? arguments,}) {  return push<T>(_routeNamed<T>(routeName, arguments: arguments)!);}

copy the code

in addition to the named route, there is an optional parameter for passing parameters on the routing page. the same goes for the method:routeNameargumentspop

void pop<T extends Object?>([ T? result ]) {  //...}

copy the code

you can carry one back to the parent page.result

code implementation

We use a list jump to the detail page to demonstrate route parameter acquisition (see Flutter Getting Started and Practical (5) for the list building article: Let’s take a list that is illustrated with text and picture). The id of the list data item that is carried when the list row is clicked jumps to the detail page. The id is returned from the details page and then the id is returned. The widget of the list item has a new id property, which is initialized when the list is built.

class DynamicItem extends StatelessWidget {  final int id;  final String title;  final String imageUrl;  final int viewCount;  static const double ITEM_HEIGHT = 100;  static const double TITLE_HEIGHT = 80;  static const double MARGIN_SIZE = 10;  const DynamicItem(this.id, this.title, this.imageUrl, this.viewCount,      {Key key})      : super(key: key);  //...}

copy the code

the container of the list uses wrapping in response to click events. the method method is defined as a method to use the get parameters returned by navigation and a display returned parameter to use . here carries an object to pass the list to the detail page.GestureDetectoronTapasyncawaitSnackBaridpushNamedMapid

@overrideWidget build(BuildContext context) {  return GestureDetector(    child: Container(      margin: EdgeInsets.all(MARGIN_SIZE),      child: Row(        crossAxisAlignment: CrossAxisAlignment.start,        children: [          _imageWrapper(this.imageUrl),          Expanded(            child: Column(              crossAxisAlignment: CrossAxisAlignment.start,              children: [                _titleWrapper(context, this.title),                _viewCountWrapper(this.viewCount.toString()),              ],            ),          )        ],      ),    ),    onTap: () async {      Map<String, dynamic> routeParams = {'id': id};      var arguments = await Navigator.of(context)          .pushNamed(RouterTable.dynamicDetail, arguments: routeParams);      ScaffoldMessenger.of(context).showSnackBar(SnackBar(        content: Text("从动态${(arguments as Map<String, dynamic>)['id']}返回"),      ));    },  );}

copy the code

A variable is also used here to receive the parameters returned by the navigation, and if the navigation has a return parameter, it will return an object, which can be received by use. Then use Convert to the actual type for use. On the details page, Flutter provides a class to get the route configuration parameters from the current context, as follows:argumentsFutureawaitasModalRoute

class DynamicDetail extends StatelessWidget {  const DynamicDetail({Key key}) : super(key: key);
@override Widget build(BuildContext context) { Map<String, dynamic> routeParams = ModalRoute.of(context).settings?.arguments;
return WillPopScope( child: Scaffold( appBar: AppBar( title: Text('动态详情'), brightness: Brightness.dark, ), body: Center( child: Text("产品 id: ${routeParams['id']}"), ), ), onWillPop: () async { Navigator.of(context).pop({'id': routeParams['id']}); return true; }, ); }}

copy the code

this is actually the parameter from our previous article route interception, so assuming we need to add additional route parameters (such as global parameters), we can reassemble the route parameters in the method. there is a place to note here, because the return carries parameters, so we need to intercept the return response event, at which point the entire component can use the package, which has two parameters:ModalRoute.of(context).settingsonGenerateRoutesettingsonGenerateRouteWillPopScope

  • child: subcomponents, i.e. the original page components;
  • onWillPop: returns pre-interception processing, returns an object, if it is , it is not returned. if so, the previous level is returned. here we call the method with parameters in order to pass the parameters back. in fact, some other processing is often done here, such as the form is not saved to ask whether to confirm li ke, and the activity page of the majority of e-commerce asks you whether you are “painful to leave” or “look at it again”. Future<bool>falsetruepop

the final effect

the final running effect is shown in the following figure, the detail page gets the parameters, and when it returns, it also receives the corresponding ones.idid

route parameter interception

Route parameters can be additionally processed by onGenerateRoute interception, as shown in the sample code below. Note that this is just an example, due to settings. Arguments can be of any type, so it can cause conversions to fail. In actual business, it is best to specify the route parameter pass type to avoid the occurrence of exceptions caused by inconsistent parameter forms.

static Route onGenerateRoute<T extends Object>(RouteSettings settings) {  var arguments = settings.arguments as Map<String, dynamic>;  if (arguments != null) {    arguments['event'] = '路由拦截增加的参数';  }  RouteSettings newSettings =      settings.copyWith(name: settings.name, arguments: arguments);
return CupertinoPageRoute<T>( settings: newSettings, builder: (context) { String name = settings.name; if (routeTables[name] == null) { name = notFoundPath; }
Widget widget = routeTables[name](context);
return widget; }, );}

copy the code

summary

this article introduces the routing parameters passing examples and the parameter modification after route interception, in the actual process, the routing parameters are generally passed to the lower level, and it is necessary to avoid passing back and forth parameters as much as possible to achieve data transmission, resulting in serious coupling between the upper and lower levels of the page. at present, this route management will also have certain inconveniences, such as the inability to pass variable parameters in the path name like the url of the web page, and the transition animation that cannot control the page jump. route management is very popular on pubs, and the next article describes how to implement page routing.flurofluro