Android-Jetpack-Navigation介绍

android studio 相关说明 | 2018-09-08 03:17

Google 2018 I/O大会上发布了新的Jetpack组件,

目前jetpack中主要包含Foundation、Architecture、Behavior、ui等四大类组件集,而Navigation是Architecture中的一个新的成员,见下图(图片来自网络):

想要使用navigation,需要Androidstudio的版本至少在3.2以上。如果您的Androidstudio版本已经是3.2以上了,那么请继续参见下面的步骤,如果不是,还请先升级Androidstudio。目前最新的Androidstudio是3.3预览版。

我们创建一个测试工程,然后创建两个即两个以上的fragment,然后尝试使用Navigation切换fragment。首先我们需要为我们的工程添加依赖,引入Navigtion相关lib库,依赖代码如下:

为了管理navigation,并使用navigation相关方法跳转,我们需要创建一个NavigationRes资源,右键res资源文件夹 : New -> Android resource file -> 输入xml文件名称并选择Resource type为Navigation -> OK,如下图:

然后我们点开新创建的文件:

接下来我们需要在这个navigation res文件中添加我们创建的fragment:

然后点击design,我们会看到我们添加的fragment:

此时我们增加一个跳转action,从first_fragment 到second_fragment,可以手动代码书写,增加acion标签,也可以点击上面的视图拖拽自动完成操作,完成后代码如下:

样式现在变更为:

为了让当前的activity可以加载并使用navigation管理相关的fragment,需要给当前的activity 添加NavHostFragment,并为NavHostFragment指定navigation资源。这里创建NavHostFragment有两种方式,一种静态方式,即在activity的layout 资源文件中添加:

如果activity是AppCompatActivity的子类,还需要复写AppCompatActivity.onSupportNavigateUp() 方法:

上述功能准备就绪,我们可以使用navigation的api来进行实际切换了。首先我们在进行切换之前需要获取NavController,navigate相关的api均封装在NavController中,获取NavController有如下静态方法:

NavHostFragment.findNavController(Fragment)Navigation.findNavController(Activity, @IdRes int viewId)Navigation.findNavController(View)

然后我们给first_fragment中的一个button添加点击事件,点击button时切换到second_fragment :

我们还可以使用如下方式快速添加:

在切换fragment的时候,我们可以增加动画,让切换看起来更顺畅,这里有两种方式添加,一种是在navigation res文件的action标签下指定:

第二种是在代码中设置NavOptions来添加切换动画:

注意回调参数NavDestination,这个会得到我们在navigation res中定义的相关信息,通过这些信息我们可以做一些特定的处理

我们发现在mNavController.navigate方法有带有Bundle参数的重载方法,因此我们可以通过Bundle传递参数:

另外Google还为我们提供了一种类型安全的参数传递方式,使用这种方式我们需要添加gradle 相关插件:

a、在 Project 下的 build.gradle添加如下依赖:

b、在 app 下的 build.gradle 里增加gradle插件调用:

c、navigation res文件中增加参数定义:

d、build下会在build->generated->source->下生成navigation-args目录,同时生成args相关类(这里有个疑问,为什么不统一生成一个公用的转换类,要使用这样的方式动态生成?):

e、代码中使用WBFirstFragmentArgs生成跳转参数的bundle:

其他的高级用法还有deep link、与Toolbar、BottomNavigationView结合使用等,这里不再详细介绍,大家有需要可自行学习。

我们创建的navigation res文件一定要指定startDestination属性,即需要设置开始时加载哪一个fragment

fragment一定要继承自android.support.v4.app.Fragment类,而不要是android.app.Fragment,否则会因类型问题导致异常。

NavController 存储在view的tag中的,设置的方法位于NavHostFragment中的onViewCreated方法中:

因此我们在查找NavController也是通过view个gettag方法,所以要想查找成功,首先当前view所在的view树中一定包含有设置R.id.nav_controller_view_tag的view。而当fragment的onViewCreated方法回调之前,这个fragment中的view是没有绑定到相关view上的,所以在这之前调用Navigation.findNavController(view) 方法会报异常(google在找不到NavController会抛出一个异常)。

我们知道fragment的切换有replace、hide、show等相关方法,那么navigate中使用的到底是什么方法呢?

我们查看代码可以其使用的是replace方式,代码位置位于FragmentNavigator中(看见FragmentNavigator这个可以想到一定还会有个ActivityNavigator):