57

Android-Jetpack-Navigation 介绍

 5 years ago
source link: https://mp.weixin.qq.com/s/aYHtaaOBjgZ2HD21VNGBnQ?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

1、初识Navigation

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

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

fYbU7z2.jpg!web

2、Navigation的基本使用

2.1、确认Android studio的版本

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

2.2、搭建测试工程,添加navigation依赖

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

NBBNneJ.jpg!web

2.3、创建navigation res资源文件

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

JvMZfyM.jpg!web

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

6nAFBzz.jpg!web

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

qQRnquA.jpg!web

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

muAbuen.png!web

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

VVfmUzF.jpg!web

样式现在变更为:

jyeaAz3.png!web

navigation资源中除了能添加fragment标签外,还能添加activity标签,方式基本同fragment,添加后效果:

fiMZNfb.png!web

2.4、修改activity使其能管理navigation

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

7J7BR3y.jpg!web

第二种是使用代码的方式给activity添加NavHostFragment:

UzuIjun.jpg!web

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

juiYZrR.jpg!web

2.5、给ui组件增加点击切换事件

上述功能准备就绪,我们可以使用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 :

Njmeue6.jpg!web

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

3、Navigation的进阶使用

3.1、增加transition动画

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

YV3UFb3.jpg!web

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

mmyQbqi.jpg!web

3.2、监听navigation切换动作

可以给NavController添加OnNavigatedListener来达到监听navigate事件目的:

QjYvUfE.jpg!web

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

3.3、navigation切换时传递参数

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

M736rqU.jpg!web

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

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

aa2YZfe.jpg!web

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

AVBrMzn.jpg!web

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

fiaMBrJ.jpg!web

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

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

QFrEzy3.jpg!web

3.4、其他

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

4、Navigation简单总结

4.1、navigation res文件需要指定startDestination属性

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

FjEf2eU.jpg!web

4.2、fragment的继承问题

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

4.3、NavController的获取时机

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

6VnEfmv.jpg!web

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

4.4、navigate方法中fragment的切换方式

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

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

b6zyuaj.jpg!web

5、参考文章

https://developer.android.google.cn/topic/libraries/architecture/navigation/

https://codelabs.developers.google.com/codelabs/android-navigation/#0

https://blog.csdn.net/cekiasoo/article/details/80739805

RBJFnaB.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK