Android日志:Jetpack Compose 导航
前言
就像传统的View一样,Compose也有导航Navigation。但是,我们都知道Jetpack Compose是声明式UI,所以其创建Navigation的方式也大为不同。下面小编将以我做过的一个手机笔记App中使用到导航的部分为例讲解如何在Compose中创建navigation。(后续也会出关于这个项目的文章)
代码案例
此为实战案例,其中涉及到navigation的知识点都会在后方讲解。
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
@ExperimentalAnimationApi
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
CleanArchitectureNoteAppTheme {
Surface(
color = MaterialTheme.colors.background
) {
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = Screen.NotesScreen.route
) {
composable(route = Screen.NotesScreen.route) {
NotesScreen(navController = navController)
}
composable(
route = Screen.AddEditNoteScreen.route +
"?noteId={noteId}¬eColor={noteColor}",
arguments = listOf(
navArgument(
name = "noteId"
) {
type = NavType.IntType
defaultValue = -1
},
navArgument(
name = "noteColor"
) {
type = NavType.IntType
defaultValue = -1
},
)
) {
val color = it.arguments?.getInt("noteColor") ?: -1
AddEditNoteScreen(
navController = navController,
noteColor = color
)
}
}
}
}
}
}
}
项目大致情况:
该项目有浏览页(主页)与添加页两个页面,通过添加页添加事件,主页也可以对相应事件进行修改。
添加依赖
就如同在View中一样,使用导航需要添加依赖
dependencies {
implementation "androidx.navigation:navigation-compose:2.4.0-beta02"
// other dependencies
}
设置导航控制器——NavController
NavController是Compose中的Navigation的核心组件,它可以跟踪返回堆栈条目、向前移动堆栈、启用返回堆栈以及在屏幕状态之间导航。因为NavController是Navigation的核心,所以必须先创建它才能导航到目的地。
在Compose中NavController可以使用rememberNavController()获取,rememberSaveable会记住配置更改后仍然存在的NavController。
此代码仅供参考,并未在上方案例出现
import androidx.navigation.compose.rememberNavController
...
@Composable
fun RallyApp() {
RallyTheme {
val allScreens = RallyScreen.values().toList()
var currentScreen by rememberSaveable { mutableStateOf(RallyScreen.Overview) }
val navController = rememberNavController()
Scaffold(...
}
为目的地准备路线
在View中,我们通常会先创建navigation的导航图的资源文件然后在导航图中添加需要导航的View。而在Compose中是否也有这样的角色呢?
那就是NavHost
NavHost中有两个关键的属性:
NavController与startDestination
NavController的作用前面已经提及
startDestination:设置导航进入的第一个页面,值是字符串,而我的项目中使用密封类封装了字符串使路径的名称易懂且封装性好。
相信读者看出来startDestination的值与后方compsable中的route属性的值有渊源,没错,这就相当于给每个composable组件添加一个标签(就相当于是View的navigation中的label)。而composable{ }中放置的每一个组件就想到于是传统意义上的View。
关于项目中封装的route
sealed class Screen(val route: String) {
object NotesScreen: Screen("notes_screen")
object AddEditNoteScreen: Screen("add_edit_note_screen")
}
使用参数导航
导航参数使路线动态化。导航参数是一个非常强大的工具,它通过将一个或多个参数传递到路由并调整参数类型或默认值来使路由行为动态化。简单来说:从此项目上的体现就是点击不同的item或点击添加事件,进入编辑页面的数据都不同。
image.pngimage.png
argument:里面放置一系列需要导航传递的参数navArgument
navArgument:封装参数
name:参数名
type:参数类型,由NavType封装
defaultValue:无参数时的默认值
此项目需要导航的参数只有note的id值以及颜色color,而参数与route之间以“?”隔开参数值需要使用$符号。每一个item的id独一无二无法更改,但是每一个item的颜色可以更改,所以项目中只传递了color作为可变参数。
navigate:同View中一样,使用导航跟换页面也是调用NavController.navigate。