一、Navigation 介绍
Navigation 是 Jetpack 组件库的一个组件,可以方便的管理 Fragment ,可以看作是针对于 Fragment 的路由。 功能主要是:用于管理 APP 页面跳转导航,同时,切换 Fragment 变得更加直观,通过可视化界面展示 Fragment 的切换流程图。
利用 Navigation 组件对 Fragment 的原生支持,可以获得架构组件的所有好处(例如生命周期和 ViewModel),同时让此组件来处理 FragmentTransaction 的复杂性。此外,Navigation 组件还可以处理转场动画。它可以自动构建正确的“向上”和“返回”行为,包含对深层链接的完整支持,并提供了帮助程序,用于将导航关联到合适的 UI 小部件,例如抽屉式导航栏和底部导航。
除此之外,Navigation 最大的一个好处是:让单 Activity 应用成为首选架构(即:单 Activity + 多 Fragment)。应用内 Fragment 页面的跳转则由 Navigation 来处理,开发者无需在处理 FragmentTransaction 的复杂性以及相关的转场动画。
二、Navigation 核心概念
- NavGraph:导航图,一个 XML 资源,它包含集中在一个位置上的所有与导航相关的信息。这包括所有单独的内容区域(destination),以及用户可以通过应用程序访问的可能路径。就类似一个流程图,如下图。
- NavHost:显示导航图中的 Destination 的容器。导航组件包含一个默认的 NavHost 实现 NavHostFragment。
- NavController: 控制 NavHost 容器内容的切换的控制器。
- Destination:目的片段,一般是 Fragment (由于 google 推荐单 Activity 模式 APP),也可以是 Activity。如下图的三个界面。
- Action:动作,就相当于 intent,表示从一个 Destination 到另一个 Destination,如下图的箭头。
三、Navigation 使用
1. 导入依赖库
implementation 'androidx.navigation:navigation-fragment:2.2.1'
implementation 'androidx.navigation:navigation-ui:2.2.1'
2. 创建一个Activity和多个Fragment
按照业务逻辑创建,假设创建了MainActivity、FragmentA、FragmentB。
3. 新建 Navigation
- 在
res
目录右键 New->New Resource File,弹出New Resource File
的对话框 - 填写 File Name 如:nav_graph,Resource type 选择
Navigation
,点击OK
4. 使用 Navigation
打开 nav_graph.xml
,底部选择 Design 选项卡,点击 New Destination
(左上角 + ) 按钮,在弹窗中选择fragment_a.xml
、fragment_b.xml;
或选择 Create blank destination
新建 Fragment 之后选显示如下界面:
5. 添加 NavHostFragment
在 Activity 布局里添加 NavHostFragment,并将 NavHostFragment 跟我们刚才创建的 navigation 关联。
如果是采用拖动添加的方式,会弹出一个包含导航图列表的对话框,选择创建的 navigation 即可;也可以使用代码指定
app:navGraph="@navigation/nav_graph"
6. 添加 Action
左键按住 fragment 右侧中间的圆圈然后拖动到要导航的 fragment 然后松手。
7. NavController 处理 Action 跳转
跳转需要通过 NavController 对象的 navigate(int id)
方法来跳转。
NavController对象获取的三种方式
NavHostFragment.findNavController(Fragment)
Navigation.findNavController(Activity, @IdRes int viewId)
Navigation.findNavController(View)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
Navigation.findNavController(view)
button.setOnClickListener {
//id就是nav_graph导航图里面的action id
Navigation.findNavController(view).navigate(R.id.action_blankFragment_to_secondeFragment)
}
}
如果是返回,就调用 navigateUp()
方法。
四、Navigation 拓展
1. Navigation 传参
(1)代码传参
可以使用 Bundle 传参:
Bundle bundle = new Bundle();
bundle.putString("param", "I AM FROM FRAGMENT-A");
Navigation.findNavController(it).navigate(R.id.action_fragmentA_to_fragmentC, bundle);
(2)导航图传参
如 A 传参到 B,在导航图设计页面,单击 destination B ,在右边的属性栏添加 Argument,弹出如下窗口:
创建成功后,fragment 标签中添加 argument 标签如下:
<argument
android:name="name"
android:defaultValue="no"
app:argType="string" />
之后可通过两种方式传递参数:
- FragmentBArgs
- FragmentADirections
它们都是自动生成的,FragmentBArgs 是根据fragment 节点下的 argument 节点生成的;FragmentADirections 是根据 action 生成的。
使用生成的对应的 Agrs 或者 Directions 来传递参数,需要导入 apply plugin: 'androidx.navigation.safeargs'。
//使用FragmentBArgs
val bundle = FragmentBArgs.Builder().setText("Hello World").build().toBundle()
Navigation.findNavController(it).navigate(R.id.action_fragmentA_to_fragmentB, bundle)
//使用FragmentADirections
val direction = FragmentADirections.action_fragmentA_to_fragmentB().setText("Hello World")
Navigation.findNavController(it).navigate(direction)
2. Navigation 动画
点击箭头,右边属性栏有个Animations列表。默认都是null,可以设置官方自带的进出栈动画,也可以设置自定义动画。
- Enter 进入一个目的地 (例如 A跳B, B显示时执行的动画)
- Exit 退出一个目的地 (例如 A跳B,A隐藏时执行的动画)
- Pop Enter通过 pop 操作进入目的地 (例如 A跳B,B navigateUp 后 A再次出现时执行的动画)
- Pop Exit 通过pop 操作退出目的地 (例如 A跳B,B navigateUp 后 B消失时执行的是这个动画)
Fighting_初心 发布了65 篇原创文章 · 获赞 66 · 访问量 2万+ 私信 关注