Navigator 2学习锦囊
- 课前:利用好图文小节做好学前功课
- 为了帮助小伙伴们爬坡,老师对课程中的技术难点都准备了对应图文教程,图文教程是爬坡的关键,一定要多看几遍,然后在学习后面的视频教程。
- 心态:不能急于一节课就能将其完全领悟
- 对于学习复杂的技术,要有一个平常心态,不能急于通过短短的一节课就能完全领悟
- 如果想吃透Navigator 2,需要结合一下几个关键步骤:
- 课前:通过图文小节熟悉Navigator 2的重要概念和主要原理
- 课中:通过视频教程学习如何在项目中使用Navigator 2
- 课后:将课程中讲的代码多敲几遍
- 后续实战:在后续实战中慢慢体会,以及消化之前没有消化的知识点
- 策略:教程多多看,课后多多练
- 策略:回过头来细体会
- 就像爬山一样,在山脚下往上看你会看到数不尽的阶梯,但当你爬到山顶在回过头来往下看的时候之前的台阶对你来说就会变得相对平坦
概述
新版Flutter包含两个版本的导航器,分别是Navigator 1.0和Navigator 2.0。Navigator 2.0是从Flutter 1.22版开始引入的一个全新的导航器,其相比1.0功能更多也更加的灵活,当然了从使用的难易程度上来说Navigator 2.0比Navigator 1.0要难上手一些。
QA:Navigator 2.0出来后Navigator 1.0还能继续用吗?
相信很多同学有这样的疑问,Navigator 2.0是对Navigator 1.0的补充,目前Flutter官方还没有将Navigator 1.0从Flutter中移除的计划,所以大家可以根据需要选择使用这两种导航器。当然了,作为从事Flutter开发的同学如果对Flutter的新特性,比如Navigator 2.0一点都不了解那么肯定是说不过去的,那么接下来我们就来重点学习下Navigator 2.0的特性、原理以及使用技巧。
QA:选择Navigator 2.0还是fluro?
fluro也是一个不错的Flutter导航框架,它和Navigator没有绝对的好与坏,主要区别是一个是社区的,一个是官方的。fluro的出现主要是解决Navigator 1.0功能弱的问题,但这在Navigator 2.0已经得到了很好的缓解。
- 如果你的项目之前是有的就是fluro,那么可以根据需要继续使用;
- 如果你的项目用的是Navigator 1.0,那么可以择机升级到Navigator 2.0;
- 如果你的项目是一个新的项目没有历史包袱,那么可以一步到位直接上手Navigator 2.0;
QA:为什么Navigator 2 比Navigator 1 复杂这么多?
- Navigator 2 为了提供对Flutter Web的支持新引入了很多的API和概念,比如:Pag、Router、RouterDelegate、RouteInformationParser,除此之外还需要自己管理路由栈,比Navigator 1 的复杂度高出了一个量级;
- 但这些API并不是必须要是要实用的,对应一个APP的导航框架来说只需要用到Router、Page、RouterDelegate就可以了,其中Router、Page的使用比较简单,主要是RouterDelegate比较复杂;
- RouterDelegate中最为核心的一点是在build方法中来实现对路由栈的管理,这个参考课程中的设计就可以了;
- 对Navigator 2的使用和理解不仅仅停留在看视频上,要参考着课程中的讲解,动手去写多写几遍,以及跟着后面的实战项目按部就班的学习,然后回过头来在来看之前不理解的部分,就会豁然开朗了;
Navigator 2.0特性
- 支持自定义页面的路由栈;
- 支持一次打开或关闭多个页面;
- 支持删除当前页面下的页面;
那这些特性能都是Navigator 1.0没有或很难实现的一个功能。
Navigator 1.0主要功能回顾
打开和关闭页面是平时开发中最常用的一个功能,那么在Navigator 1.0中最常用的打开和关闭页面的方式是什么呢?
打开一个页面
Navigator.push(context, MaterialPageRoute(builder: (context) => page));
关闭一个页面
Navigator.pop(context);
以上打开和关闭页面的实现也是Navigator 1.0最常用的方式之一,也是咱们《Flutter从入门到进阶 实战携程网App》课程中用的最多的一种导航方式。
走进Navigator 2.0
Navigator 2.0 提供了一系列全新的接口,可以实现将路由状态成为应用状态的一部分,并提供解析来自底层平台如:(Web URL)的路由的功能,新增的 API 如下:
- Page:用来表示 Navigator 路由栈中各个页面的不可变对象;
- Page是个抽象类通常使用它的派生类:MaterialPage或CupertinoPage;
- Router:用来配置要由 Navigator 展示的页面列表,通常,该页面列表会根据系统或应用程序的状态改变而改变;
- 除了可以直接使用Router本身外还可以使用MaterialApp.router()来创建Router;
- RouterDelegate:定义应用程序中的路由行为,例如 Router 如何知道应用程序状态的变化以及如何响应;
- 主要的工作就是监听RouteInformationParser和应用状态,并使用当前列表来构建Pages;
- RouteInformationParser:可缺省,主要应用与web,持有RouteInformationProvider 提供的 RouteInformation ,可以将其解析为我们定义的数据类型;
- BackButtonDispatcher:响应后退按钮,并通知 Router
Tips:上面API中BackButtonDispatcher是用到的情况很少,另外对应移动端APP开发来说我们只需要用到Navigator 2.0 中的Page、Router、RouterDelegate这三个API即可,RouteInformationParser与RouteInformationProvider主要是应用于开发web网站的路由用的;
下图展示了 RouterDelegate 与 Router、RouteInformationParser 在一起的交互和应用程序的状态:
流程解析:
- 当系统打开新页面(如 “/detail”)时,RouteInformationParser 会将其转换为应用中的具体数据类型 T(如:BiliRoutePath);
- 该数据类型会被传递给 RouterDelegate 的 setNewRoutePath 方法,我们可以在这里更新路由状态;
- notifyListeners 会通知 Router 重建 RouterDelegate(通过 build() 方法);
- RouterDelegate.build() 返回一个新的 Navigator 实例,并最终展示出我们想要打开的页面;