前言
导航(Navigation )指的是用户在应用中的前进和后退操作。导航很大程度上和业务逻辑相关。但是,在传统的Android应用开发中,导航需要开发者自己处理,对应的backstack也需要开发者自行维护,与业务相关的导航逻辑也要硬编码在Java代码中。而同时期的iOS应用开发框架早就提出了导航图的概念,并对导航进行了框架级别的抽象和支持。
为了解决类似问题,简化Android应用开发,Google在2018年推出了Jetpack。Jetpack是一套库、工具和指南,可帮助开发者更轻松地编写优质应用。在Jetpack中,Android第一次以Navigation组件的形式对用户的导航行为进行了抽象和封装,不仅简化了开发流程,还通过遵循一套既定原则来确保一致且可预测的用户体验,从而实现了代码可维护性和用户体验一致性的完美结合。
概览
Jetpack导航组件由以下三个关键部分组成:
- 导航图(Navigation graph):在一个XML文件中集中定义所有导航相关信息的,它包括应用内的所有导航目标以及所有可能的导航路径。
- 导航容器(NavHost):显示导航目标的容器。Jetpack提供了一个默认的导航容器实现NavHostFragment。
- 导航控制器(NavController):在导航容器中管理导航对象。当用户在应用中前进或者后退时,导航控制器决定下一个将要显示的内容。
功能
JetpackNavigation组件提供以下几个功能:
- 封装Fragment事务:Navigation组件封装了Fragment事务,从而简化了开发者的工作。
- 为过场动画提供标准化支持:开发者只需要专注于定义过场动画本身。
- 传递参数:通过Safe Args插件,开发者可在导航目标之间传递类型安全的数据。
实战
我们的实战是基于Google的Jetpack Navigation Codelab。它的最终效果是这样:
这是3个简单的Fragment之间跳转的情景,经过过场动画的修饰,它们之前的切换非常流畅自然。接下来,我们就通过代码来详细讲解Fragment导航是如何实现的。
首先,在build.gradle中添加以下依赖:
dependencies {
...
//Navigation
implementation "androidx.navigation:navigation-fragment-ktx:$rootProject.navigationVersion"
implementation "androidx.navigation:navigation-ui-ktx:$rootProject.navigationVersion"
}
新建两个Fragment。其中,第二个Fragment会根据传入的参数决定要加载的UI:
class HomeFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.home_fragment, container, false)
}
}
class FlowStepFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return when (flowStepNumber) {
2 -> inflater.inflate(R.layout.flow_step_two_fragment, container, false)
else -> inflater.inflate(R.layout.flow_step_one_fragment, container, false)
}
}
}
新建导航视图文件(mobile_navigation.xml)
打开导航视图文件,进行可视化编辑,包括新增Fragment,或者连接Fragment:
我们打开导航视图文件的Text标签,进入XML的编辑页面,并进行如下配置: