Flutter笔记(八):route、路由管理

什么是路由route

1、熟悉前端的朋友知道,这跟web开发中单页应用的Route概念意义是相同的;
2、Route在Android中通常指一个Activity,在iOS中指一个ViewController;
3、路由入栈(push)操作对应打开一个新页面,路由出栈(pop)操作对应页面关闭操作;比如android中就是startActivity和finish;
4、路由管理主要是指如何来管理路由栈。

Navigator

Navigator是一个路由管理的组件,它提供了打开和退出路由页方法。Navigator通过一个栈来管理活动路由集合。
常用的两个方法:
Future push(BuildContext context, Route route)
将给定的路由入栈(即打开新的页面),返回值是一个Future对象,用以接收新路由出栈(即关闭)时的返回数据。

  @optionalTypeArgs
  static Future<T> push<T extends Object>(BuildContext context, Route<T> route) {
    return Navigator.of(context).push(route);
  }

bool pop(BuildContext context, [ result ])
将栈顶路由出栈,result为页面关闭时返回给上一个页面的数据。

  @optionalTypeArgs
  static bool pop<T extends Object>(BuildContext context, [ T result ]) {
    return Navigator.of(context).pop<T>(result);
  }

MaterialPageRoute

MaterialPageRoute 是Material组件库提供的组件,它可以针对不同平台,实现与平台页面切换动画风格一致的路由切换动画:

  MaterialPageRoute({
    @required this.builder,  //是一个WidgetBuilder类型的回调函数,返回新路由的实例。
    RouteSettings settings,  //包含路由的配置信息,如路由名称、是否初始路由(首页)。
    this.maintainState = true,  //是否释放所占用的所有资源
    bool fullscreenDialog = false,  //新的路由页面是否是一个全屏的模态对话框
  })

Navigator+MaterialPageRoute

点击关于跳转到About页面

onTap: () {
    Navigator.push(context, MaterialPageRoute(builder: (context) => (About())));
}
3.jpg

命名路由

所谓“命名路由”(Named Route)即有名字的路由,我们可以先给路由起一个名字,然后就可以通过路由名字直接打开新的路由了,这为路由管理带来了一种直观、简单的方式。

注册路由表

Map<String, WidgetBuilder> routes;

它是一个Map,key为路由的名字,是个字符串;value是个builder回调函数,用于生成相应的路由widget。我们在通过路由名字打开新路由时,应用会根据路由名字在路由表中查找到对应的WidgetBuilder回调函数,然后调用该回调函数生成路由widget并返回。
可以理解成
www.xxx.com/ 进入首页
www.xxx.com/about 进入关于我们页面

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      initialRoute: "/",
      theme: ThemeData(primarySwatch: Colors.green, primaryColor: Colors.white),//设置App主题
      routes: {
        "/":(context)=>MyHomePage(),
        "/about":(context)=>About()
      },
    );
  }
}

通过路由名打开新路由页

  @optionalTypeArgs
  static Future<T> pushNamed<T extends Object>(
    BuildContext context,  //上下文
    String routeName, {    //路由名
    Object arguments,      //页面传参
   }) {
    return Navigator.of(context).pushNamed<T>(routeName, arguments: arguments);
  }

通过routeName跳转

onTap: () {
  Navigator.pushNamed(context, "/about");
  //Navigator.push(context, MaterialPageRoute(builder: (context) => (About())));
},

路由参数传递

普通push传递参数

class OtherGank extends StatelessWidget {
  final String content;

  OtherGank({Key key, this.content}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    var args=ModalRoute.of(context).settings.arguments;
    return Scaffold(
      appBar: AppBar(
        title: Text("其他Gank项目"),
      ),
      body: Center(child: Text(args==null?content:args)),
    );
  }
}
Navigator.push(context, MaterialPageRoute(builder: (context) => (OtherGank(content: "这是route传递的参数",))));

命名路由参数传递
传递

Navigator.pushNamed(context, "/other",arguments: "这是route传递的参数");

接收

var args=ModalRoute.of(context).settings.arguments;
4.jpg

路由返回值

接收返回参数

onTap: () async {
  var res = await Navigator.pushNamed(context, "/other",arguments: "这是route传递的参数");
  LogUtils.log(res);
},

传递返回参数

body: Center(child: RaisedButton(
  onPressed: (){
    Navigator.pop(context,"我要带返回值回去~");
  },
  child: Text("带参数回去"),
)),
5.jpg

点击button返回的就是带了参数的,点击AppBar的返回按钮则为null。也就是说点击AppBar的返回按钮执行的是

Navigator.pop(context)

路由钩子

当使用命名路由跳转时在跳转之前可以做统一的登录判断权限判断之类的事情。

MaterialApp(
  ... //省略无关代码
  onGenerateRoute:(RouteSettings settings){
      return MaterialPageRoute(builder: (context){
           String routeName = settings.name;
       // 如果访问的路由页需要登录,但当前未登录,则直接返回登录页路由,
       // 引导用户登录;其它情况则正常打开路由。
     }
   );
  }
);
  • 注意,onGenerateRoute只会对命名路由生效。

更详细的资料

《Flutter实战》路由管理

完整代码

https://github.com/leiyun1993/FlutterDemo-GankIO
ps:以上完整代码为Demo代码。本文中的代码只为了测试路由功能,可能在项目中无法找到完全一样的代码!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,539评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,594评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,871评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,963评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,984评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,763评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,468评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,357评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,850评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,002评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,144评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,823评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,483评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,026评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,150评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,415评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,092评论 2 355

推荐阅读更多精彩内容