Navigation是Jetpack下面的一个组件库,可以使用Navigation组件对所有页面的路由导航进行统一的管理。
为了方便学习Navigation,首先可以使用Android Studio创建一个Bottom Navigation Activity 工程,该项目的页面切换就是用的Navigation组件进行实现的,我们可以查看该工程的实现去研究Navigation的导航处理流程。
MainActivity的布局文件:
查看MainActivity的布局文件可以发现,MainActivity的页面内容部分是一个fragment标签,请注意以下几点:
android:name属性包含NavHost实现的类名称。app:navGraph属性将NavHostFragment与导航图相关联。导航图会在此NavHostFragment中指定用户可以导航到的所有目的地。app:defaultNavHost="true"属性确保您的NavHostFragment会拦截系统返回按钮。请注意,只能有一个默认NavHost。如果同一布局(例如,双窗格布局)中有多个主机,请务必仅指定一个默认NavHost。
android:name属性指定androidx.navigation.fragment.NavHostFragment,NavHostFragment继承自Fragment实现了NavHost接口,在onCreate中会创建一个NavHostController实列,并对NavController进行了一些列处理,NavHostFragment导航相关的处理逻辑主要放在NavHostController中。NavHostController是NavController的子类,NavController有两个成员变量:mGraph和NavigatorProvider。如图:
在NavController的构造方法中,会通过NavigatorProvider的addNavigator将NavGraphNavigator和ActivityNavigator加入到NavigatorProvider的mNavigators变量中。
mNavigators是一个HashMap,用来存储各种类型的Navigator。
NavGraphNavigator和ActivityNavigator都继承自抽象类Navigator,都是Navigator处理不同类型导航的实现。子类通过实习Navigator的createDestination和navigate方法完成创建和导航对应类型的页面节点。
Navigator有四个实现类:
- NavGraphNavigator:负责处理导航图指定的
app:startDestination="@id/navigation_home" - ActivityNavigator:处理Activity的导航
- FragmentNavigator:处理Fragment的导航
- DialogFragmentNavigator:处理DialogFragment的导航
在NavHostFragment的onCreate中创建出NavHostController之后,会对NavHostController进行相关的设置,其中会调用onCreateNavController将DialogFragmentNavigator和FragmentNavigator添加到NavController的成员变量mNavigatorProvider的HashMap中。
app:defaultNavHost指定是否与系统的返回键相关联,如果为true,表示与系统的返回键相关联,当点了返回键,NavHostFragment会判断回退栈里面是否有Fragment存在,如果有会拦截系统返回键;如果没有就执行系统返回键的默认行为。
app:navGraph表示页面路由结构。当前指定了"@navigation/mobile_navigation",在NavHostFragment的onInflate方法中会获取该属性,并赋值给mGraphId成员变量。
在NavHostFragment的onCreate方法中,会通过mNavController的setGraph方法该id通过NavInflater加载为一个NavGraph对象,赋值给NavController的mGraph变量,并导航到指定的startDestination页面节点。
至此,Navigation就完成了启动页面的导航工作。
总结:NavHostFragment作为页面内内容的承载者,在它的onCreate方法中创建了NavHostController,也就是我们页面路由导航的入口类、关键类,我们所有的路由跳转都由它完成。NavHostController内有两个非常重要的全局变量NavigatorProvider和NavGraph。NavigatorProvider本质上是一个HashMap,它里面内置了四种导航器:NavGraphNavigator、ActivityNavigator、FragmentNavigator、DialogFragmentNavigator。NavGraph在创建的时候收集所有的页面节点信息——Destination对象。每种Destination对象有相应的Navigator来创建,并且在跳转的时候有相应的跳转行为。
通过研究知道了Navigation框架内置了哪几种Navigator,也了解了Navigator是如何创建页面节点信息Destination对象的,也了解了Navigator是如何完成页面跳转的,最后也了解了如何根据app:navGraph解析相应的NavGraph对象。
参考文章: