Flutter基础: 路由管理

Flutter的设计貌似对前端同学比较友好,言归正传,先从原理开始,然后是具体的case,好,我们开始:

小提示:电脑端阅读更佳

1. 路由工作原理:

对于原来移动端开发的同学,多了件事情,管理路由。简单讲路由的工作原理是通过路由对象的进出栈来使用户从一个页面跳转到另一个页面。

2. 路由是什么?

在Flutter 中理解好路由(Route), 离不开另一个概念导航(Navigator), Flutter中路由管理, 主要依赖的是 Navigator(导航器)类, 这是一个用于管理一组具有某种进出规则的页面的 Widget, 也就是说用它我们能够实现各个页面间有规律的切换, 而这里的规则便是在其内部维护的一个“ 路由栈。

3. 路由的种类:

路由分为 组件路由,命名路由,自定义路由,嵌套路由。

4. 使用方法:

Navigator:导航器,负责管理路由
路由名称命名:路由名称通常使用路径结构:“/a/b/c”,主页默认为 “/”。

4.1 PUSH 使用

1. pushNamed
Navigator.of(context).pushNamed('routeName');
简单的将我们需要进入的页面push到栈顶,以此来显示当前页面,其参数是一个字符串类型,传入的是页面对应的路由名称 该路由名称需要在程序主入口中进行定义:

void main() {
  runApp(
    new MaterialApp(
         home: new Screen1(),
         routes: <String, WidgetBuilder> {
          '/screen1': (BuildContext context) => new Screen1(),
          '/screen2': (BuildContext context) => new Screen2(),  
          '/screen3': (BuildContext context) => new Screen3(),
 },   ));}

2.pushReplacementNamed
Navigator.of(context).pushReplacementNamed('routeName');

指把当前页面在栈中的位置替换成跳转的页面(替换导航器的当前路由,通过推送路由[routeName]),当新的页面进入后,之前的页面将执行dispose方法。

下面为官方说明:
Replace the current route of the navigator that most tightly encloses the given context by pushing the route named [routeName] and then disposing the previous route once the new route has finished animating in.

Case Study:
从SplashScreen到HomeScreen。它应该只显示一次,用户不应该再从主屏幕回到它。在这种情况下,由于我们将要进入一个全新的屏幕, 我们可能想要使用这个方法来实现它的enter animation属性。

3.pushReplacement
特点:可以通信,页面间传递参数

Navigator.pushReplacement( context, MaterialPageRoute(builder: (BuildContext context) => screen4(param)));

4. popAndPushNamed
Navigator.popAndPushNamed(context, 'routeName');

指把当前页面在栈中的位置替换成跳转的页面(替换导航器的当前路由,通过推送路由[routeName]),当新的页面进入后,之前的页面将执行dispose方法。

下面为官方说明:
Replace the current route of the navigator that most tightly encloses the given context by pushing the route named [routeName] and then disposing the previous route once the new route has finished animating in.

Case Study:
例如 在购物应用中,有产品列表,用户在产品列表中可以通过筛选,来进一步选择商品,在这个过程中,用户点击筛选按钮时,会进入筛选条件选择界面,当用户点击 确定筛选按钮时,应弹出筛选界面,并使用新的筛选条件进入产品列表。这种情况popAndPushNamed就更合适了。

5. pushNamedAndRemoveUntil
Navigator.of(context).pushNamedAndRemoveUntil('routeName', (Route<dynamic> route) => false);

指将制定的页面加入到路由中,然后将其他所有的页面全部pop, (Route route) => false将确保删除推送路线之前的所有路线。 这时候将打开一个新的routeName页

Case Study:
使用情况:例如 当用户点击了退出登录时,我们需要进入某一个页面(比如点退出登录后进入了登录页),这个时候用户点击返回时不应该能进入任何一个页面,这种情况就可以使用。

6. pushAndRemoveUntil
Navigator.pushAndRemoveUntil( context, MaterialPageRoute(builder: (BuildContext context) => new screen4()), ModalRoute.withName('/'))

7. popUntil
Navigator.popUntil(context, ModalRoute.withName('routeName'));

4.2 POP 使用

1. maybePop
Navigator.of(context).maybePop();

maybePop 会自动进行判断,如果当前页面pop后,会显示其他页面,不会出现问题,则将执行当前页面的pop操作 否则将不执行。

Case Study:
如果我们在初始路由上并且有人错误地试图弹出这个唯一页面怎么办? 弹出堆栈中唯一的页面将关闭您的应用程序,因为它后面已经没有页面了。这显然是不好的体验。 这就是 maybePop() 起的作用。

2.canPop
Navigator.of(context).canPop();

canPop 判断当前页面能否进行pop操作,并返回bool值

3.pop
Navigator.of(context).pop();

直接退出当前页面

4.3 Popup routes(弹出路由)

路由不一定要遮挡整个屏幕

4.4 自定义路由

创建自己的一个窗口z组件库路由类(如 PopupRoute,ModalRoute 或 PageRoute)的子类
可以做什么:
- 动画
- 路径的动画
- 路径的模态屏障的颜色
- 行为以及路径的其他各个特性

Navigator.push(context, PageRouteBuilder(

  opaque: false, //这个属性不会遮挡屏幕

  pageBuilder: (BuildContext context, _, __) {return Center(child: Text('My PageRoute'));},
 
  transitionsBuilder: (___, Animation<double> animation, ____, Widget child) {

  return FadeTransition(

     opacity: animation,

     child: RotationTransition(

         turns: Tween<double>(begin: 0.5, end: 1.0).animate(animation),

         child: child,),

);}));
4.5 嵌套路由

一个应用程序可以使用多个路由导航器。将一个导航器嵌套在另一个导航器下方可用于创建“内部旅程”

4.6 数据传递和数据返回(页面间的通信)

1. 数据传递
Navigator.push(context, new MaterialPageRoute(builder: (BuildContext context) => new mainPage(params)));

  • 在需要接收参数的页面进行参数定义
  • 将参数添加到构造函数中
  • 使用MaterialPageRoute并在页面中传入参数即可

2.数据返回

2.1 Navigator.of(context).pop('这是页面5返回的参数'); 在pop中写上返回的的值,这时候在上方的then中即可得到返回的数据。

2.2

方法一:

String userName = "yinll";
Navigator.push( context, new MaterialPageRoute( 
      builder: (BuildContext context) => 
        new Screen5(userName)))
        .then(
            (data){ result =data; print(result); 
});

方法二:

onTap: () async {
         String result = await Navigator.push( context, new MaterialPageRoute( 
                builder: (context) => new ContentScreen(articles[index]), ), );
                if (result != null) { 
                    Scaffold.of(context).showSnackBar( 
                            new SnackBar( content: new Text("$result"), duration: const Duration(seconds: 1), ), ); 
}}
最佳实践(实用):
  1. 认识路由,一个轻量级的路由管理本质是页面标识(页面路径)与页面实例的映射

  2. 传统的做法弊端

    1. 每个映射的维护影响全局映射配置的稳定性,每次维护映射管理时需要脑补所有的逻辑分支.

    2. 无法做到页面的统一抽象,页面的构造器和构造逻辑被开发者自定义.

    3. 映射配置无法与页面联动,把页面级的配置进行中心化的维护,导致维护责任人缺失.

  3. 最佳实践:路由注解方案(这里是一位阿里同学给出的方案)

    1. annotation_route

    2. 注解方案设计图


      image.png

参考链接:

  [https://medium.com/flutter-community/flutter-push-pop-push-1bb718b13c31](https://medium.com/flutter-community/flutter-push-pop-push-1bb718b13c31)

  [https://juejin.im/post/5be2d6546fb9a049be5cf6d5#heading-0](https://juejin.im/post/5be2d6546fb9a049be5cf6d5#heading-0)

  [https://juejin.im/post/5bbaf7bf5188255c8d0fe309#heading-9](https://juejin.im/post/5bbaf7bf5188255c8d0fe309#heading-9)

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

推荐阅读更多精彩内容

  • 路由初体验 路由(Routes)是什么?路由是屏幕或应用程序页面的抽象。 Flutter 使我们能够优雅地管理路由...
    Meandni阅读 4,228评论 0 16
  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi阅读 7,322评论 0 10
  • 我们家的大白菜 五年级一班吴子涵 说到白菜,它可是我们最熟悉不过的蔬菜了,它的叶片白嫩如玉脂,看起来就好吃,真想一...
    童声童话阅读 787评论 0 1
  • 昨晚十一点多休息,今晨六点半起床。中间有浅睡。 昨天李大夫把脉,不但能把出身体状态,还能把出心理状态。身体方面:1...
    张玉民阅读 719评论 0 7
  • 中午闲暇期间,大家都在整理自己的东西。 同事A突然像发现了新大陆一样,摸着自己的胳膊,震惊地说道:“你看,我这怎么...
    萍栏阅读 369评论 1 7