navigation根节点中有个startDestination字段,他表示的是默认展示的是哪一个页面。通过fragment标签来定义要路由的相关页面。id为fragment唯一标识。name为包名,必须保证正确。layout为fragment的布局文件,配置后方便在Design视图中查看。
fragment中配置了子节点 action 。action表示的就是具体要路由的行为。同样id也是其唯一标识,destination表示的是目的地,即需要路由到具体的某一个页面。popUpTo表示弹出到某一个页面。action还有其他的属性比如配置动画等,具体请看Demo。
** NavHostFragment是导航视图的展示容器。**
name为固定写法,必须指明为
androidx.navigation.fragment.NavHostFragment
defaultNavHost字段表示是否拦截返回按键操作。
若为true,需要的Activity中重写onSupportNavigateUp方法。
因为默认情况下返回键是不会回退fragment页面的。
override fun onSupportNavigateUp(): Boolean {
return findNavController(R.id.nav_host_fragment).navigateUp()
}
navGraph字段即为我们配置的navigation导航视图。
NavController
通过findNavController来获取NavController,通过controller的navigate或者navigateUp进行页面之间的路由操作。
那么在三个页面的点击按钮的逻辑就是挑战相应的页面:
mBtn.setOnClickListener {
Navigation.findNavController(it).navigate(R.id.fragment1_action)
}
通过指定action的id来告诉Navigation跳转的逻辑。其他页面也是一样。
最终效果:
我们来总结下 navigation、NavHostFragment以及NavController之间的关系。
navigation就是规划了很多的路线,而这些路线需要在NavHostFragment中才能进行展示。展示后这么多的路线该怎么走呢,决定权就在NavController手中了,就像是方向盘一样,控制着该走哪一个路线。
传递参数
在上文中我们讲解了navigation相关的知识,其中还有一个子标签:argument。是用来定义参数的。比如我们在fragment2标签中添加argument标签如下:
那么在fragment1跳转到fragment2的时候就可以携带参数了。其中 name 表示参数名称。defaultValue即为默认值。argType为参数的类型。nullable表示是否可以为空。
fragment之间传递参数有两种方式:
- 传统的Bundle方式
- 通过谷歌提供的safeArgs
传统的Bundle方式
通过Bundle来设置和获取参数。
在fragment1中进行设置:
mBtn.setOnClickListener {
//如果要使用 xml中argument的默认值则直接new Bundle() 传入即可
val args = Bundle()
args.putString(“name”,“通过bundle传递参数”)
Navigation.findNavController(it).navigate(R.id.fragment1_action, args)
}
在fragment2中进行获取参数:
val args = arguments
val name = args?.getString(“name”)
mTvName.text = name
这样就可以将参数进行传递了。上面这种方式大家有没有觉得有什么问题呢?
参数名称 “name” 我们在三处进行的手动填写。这样会很容易导致拼写错误以及修改的时候容易漏改。很不友好。所以谷歌给我们提供了一个插件:safeArgs。下面我们来看下具体使用。
safeArgs
首先需要进行配置,在项目的 build.gradle 中添加classpath配置:
dependencies {
classpath ‘android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0’
}
再在app的 build.gradle添加 apply plugin。
apply plugin: ‘androidx.navigation.safeargs’
项目重新构建后会知道为fragment生成后缀为 Directions的文件。并为navigation中有 argument 标签的fragment自动生成后缀为Args的文件。
通过后缀为 Directions的文件进行参数的设置。后缀为Args的文件进行参数的获取。
fragment1中进行设置:
mBtn.setOnClickListener {
val args = Fragment1Directions.fragment1Action().setName(“通过safeArgs进行参数传递”)
Navigation.findNavController(it).navigate(R.id.fragment1_action, args.arguments)
}
fragment2中进行获取:
val name = Fragment2Args.fromBundle(arguments!!).name
mTvName.text = name
这样就完成了fragment之间参数的传递。完全避免了手动设置参数的逻辑。直接通过setter和getter进行参数的操作。
总结
最后
只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。
真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。
腾讯、字节跳动、阿里、百度等BAT大厂 2019-2021面试真题解析
资料太多,全部展示会影响篇幅,暂时就先列举这些部分截图
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!
析**
[外链图片转存中…(img-9WYpzSER-1715362177420)]
资料太多,全部展示会影响篇幅,暂时就先列举这些部分截图
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!