坑🕳路由

2018-07-27  本文已影响54人  _白羊

参考来源:https://segmentfault.com/a/1190000015150843
路由:

概述:flutter中的默认导航分成两种,一种是命名的路由,一种是构建路由。

命名路由:缺点是不能传递参数
这种路由需要一开始现在创建App的时候定义Route

new MaterialApp(
      ....
      routes: {
        "nameRoute":(BuildContext context)=>new FirstPage(),
      },
    );

然后就可以在程序中使用Navigator.pushNamed来跳转

Navigator.pushNamed(context, "nameRoute");

构建路由
在Navigator.push的时候使用自定义方法构建一个路由

Navigator.push(context, new MaterialPageRoute(builder: (BuildContext context){
   return new SecondPage(title:"请输入昵称");
}))

返回上一页并携带参数
A路由跳转到B路由
B路由:通过Navigator.pop(context),返回上一级路由

Navigator.pop(context,"携带参数");

接收路由返回的参数
push系列的方法返回值是一个Future,可以用来接收参数
A路由:

Navigator.pushNamed<String>(context, "routeName").then( (String returnValue){
   //处理代码
});

 Navigator.push<String>(context, new MaterialPageRoute(builder: (BuildContext context){
    return new SecondPage(title:"传递的参数");
  })).then( (String result){
       //处理代码
  });

遇到的坑
如果把页面路由跳转的方法单独进行封装,拿到返回值后,直接通过return 返回返回值为null(应该是可以通过async和awite结合的方式实现的),最后通过使用回调函数解决的。

/* 从右向左滑动进入页面 */
launchPage(BuildContext context, page, cb) {
  Navigator
      .push(
    context,
    new PageRouteBuilder(
      opaque: true,
      pageBuilder: (BuildContext context, _, __) {
        return page;
      },
      transitionsBuilder:
          (___, Animation<double> animation, ____, Widget child) {
        return new SlideTransition(
          child: child,
          position: new Tween(
            begin: const Offset(1.0, 0.0),
            end: Offset.zero,
          ).animate(animation),
        );
      },
    ),
  ).then((returnValue) {
    if (returnValue != null && cb !=null ) {
      cb(returnValue);
    }
  });
}

调用跳转方法并拿到返回值

onTap: () {
  launchPage(
  context,
  new ChangeMaterials(),
  (returnValue) {
     // 处理返回值          
},

拓展:在Flutter中startActivityForResult等价于什么(作者:catsuo,链接:https://juejin.im/post/5a96cd1f5188257a780de9a0,来源:掘金)

在Flutter中可以使用Navigator类获取从当前Route返回到上一个Route时附带的数据信息。只需要对push返回的Future对象做一个await操作。关于Future,await,async不太清楚可以参阅官方文档,他们用来在Dart中实现异步同步功能。
比如我们需要启动一个位置信息界面让用户选择他们所处的位置,我们可以写下面的代码:

Map coordinates = await Navigator.of(context).pushNamed('/location');

此处通过pushNamed方法将屏幕上的当前界面跳转到了一个位置信息界面(假设我们已经配置好了/location对应的Route)。同时pushNamed会返回一个Future对象,我们需要将该Future对象作为await的表达式。
然后在我们的显示位置信息的界面中当用户选择好位置后我们就通过pop当前的Route出栈来实现返回上一个界面的效果,并同时带上需要返回给上一个界面的数据信息:

Navigator.of(context).pop({"lat":43.821757,"long":-79.226392});

复制代码pop的参数就是返回给上一个界面的数据信息,这里是一个Map类型的数据。表示位置信息的Route出栈后,上面的await表达式将被唤醒,并且接收到传递过来的Map数据。
小结:
在Flutter中使用Navigator向Route Stack中push一个Route时返回的是一个Future对象,通过await表达式可以实现等待界面返回的效果,并且Navigator从Route Stack中pop一个Route时可以带上参数,此时带的参数就会返回给唤醒的await表达式。进而实现类似startActivityForResult中的当前界面返回并传递参数给上一个界面的效果。

Flutter 中,对话框、菜单、下拉选项等都是通过创建路由显示的(本条来源:https://www.jianshu.com/p/46fbca731434

image.png
image.png
上一篇 下一篇

猜你喜欢

热点阅读