Navigation学习整理

499 阅读3分钟

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对象。

参考文章:

Navigation 组件使用入门