Flutter界面跳转-Navigator
Flutter中通过Navigator实现的页面跳转和控制,实现像安卓中的Activity跳转一样的功能。对于学习Flutter而言,必须要先掌握这些跳转的基础知识,而后才能继续往后学习。
路由
和大多数导航路由工具一样,Navigator也是使用的栈的数据结构来管理路由表的。在安卓中,每个界面被称为一个Activity,而在Flutter中每个界面就是一个路由PageRoute,对路由的管理即是对界面的管理。
Navigator将路由分为匿名路由和实名路由,匿名路由就是一个单独的Route,路由内部通过builder去构建界面的widget树,想要跳转到哪个界面,只需要将Route添加到路由栈中即可。
实名路由则是给每个Route起一个独一无二的名字,然后通过路由表将名字和路由进行映射,后续跳转时只需要传入路由名字,Navigator会自动从路由表中找到对应的路由进行入栈操作。
匿名路由跳转
路由跳转即是路由的入栈和出栈,对应的方法也是我们非常熟悉的push和pop。
1 | |
使用方式非常简单,直接通过Navigator.push调用即可,第二个参数即是界面路由Route,注意这里的Route是一个抽象类,实际中可以传入各种路由,如PageRoute、DialogRoute、PopRoute等等,根据实际进行选择。
1 | |
如上我们有一个Page1的界面,如果我们想要从其他界面界面跳转,只需要将Page1包裹成PageRoute,然后通过Navigator.push跳转即可。
1 | |
例如上面这个例子,在首页中有一个按钮,当按下按钮时就会通过push跳转到Page1界面。这里用的PageRoute是MaterialPageRoute,也可以换成iOS风格的CupertinoPageRoute它们的区别就是跳转动效不同。
1 | |
在settings中,可以设置路由的名字和参数,作为匿名路由,我们不需要设置名字,但是可能需要设置参数,用于界面间的数据交互。
1 | |
参数arguments是一个Object类型的数据,数据在子界面中通过ModalRoute获取。
1 | |
以上是匿名路由的跳转方式,总结下来就是构建一个MaterialPageRoute,然后通过Mavigator.push进行跳转,参数传递则是放在了PageRoute的settings参数中。而返回也是非常简单,正常返回可以直接按返回键或者通过手势返回,也可以通过pop方法进行返回。
1 | |
很简单,直接调用pop方法即可,如果想要给上一个界面传递参数的话,则通过pop的第二个参数传递即可。
1 | |
例如我们点击按钮时,给上一个界面返回一个hello的字串:
1 | |
以上就是匿名路由的跳转和返回的方法,以及跳转参数传递和返回参数回传的方式。实际上还有几个跳转方式也是比较常用的,例如pushAndRemoveUntil方法。
1 | |
它相对于普通的跳转,多了一个predicate参数。该跳转方式是跳到新的路由中,然后清除路由栈中已存在的路由,直到predicate返回true为止。
1 | |
如上例,就是当跳转到Page3界面时,移除栈内已有的名称为home的路由之上的所有路由,不包括home,当然,对于这种判定名称来决定是否移除的场景,可以直接使用ModalRoute.withName来构建predicate。
同理,对于界面返回时也是有一个相同类型的方法的,popUntil也是比普通的pop多一个参数,用来判断需要移除多少个界面。
1 | |
当需要返回时,可以通过该方法进行返回,它会一直将栈顶界面移除,直到predicate返回true。
实名路由跳转
以上看的都是匿名路由的跳转方式,实际上匿名路由的使用场景是非常少的,大部分都会采用实名路由来实现路由管理。实名路由是给每个路由设置一个名字,并且将其存放在路由表中进行管理,后续跳转时直接传入路由名称,而不需要传入路由实体即可。
1 | |
路由表的设置是在应用的最顶层的MaterialApp中设置的,主要设置两个参数,一个是initialRoute表示初始路由,一个是routes的集合存放的是各种路由。在路由的map集合中,路由名称是可以随便定义的,类型是字符串类型,注意,通常情况下,将/定义为首页,如果路由表中存在/路由的话,初始化路由initialRoute可以省略不写。
路由跳转使用的是pushNamed:
1 | |
和push相比, 参数从route变成了routeName,也就是说不需要我们手动去创建Route了,因而也无法设置settings来传递参数了,所以这个方法额外提供了一个参数arguments用来传递参数。
在下一个界面中获取传递的参数方式还是一样的ModalRoute.of(context)!.settings.arguments。
和匿名路由相对应的,还有一个pushNamedAndRemoveUntil,也是跳转一个新的路由界面时,移除已存在的路由,直到predicate返回true。
1 | |
界面返回的方法是共用的,pop和popUntil两种返回,但是多了一个popAndPushNamed,该方法是移除当前界面时,加入一个新的界面,类似于替换。
1 | |
总结
默认的路由导航Navigator比较简单,主要的就是路由的跳转和返回,以及跳转时的参数携带。这里又分为了实名路由和匿名路由,匿名路由直接通过Navigator进行跳转即可,直接传入对应的路由即可,但是这种方式对路由的管理比较混乱,因此实际中用的也比较少。
实名路由是通过路由表进行管理的,路由表定义在MaterialApp中,以Map的数据结构进行管理,key是路由名称,对应的是字符串类型,value是一个函数类型,用于构建界面的Widget树。跳转是通过名称进行跳转,而不用传入实际的路由,项目中基本都使用实名路由的方式进行管理。
