上几篇文章 我们分别实现了 Compose Bloom项目的各个页面,包括欢迎页、登录页和主页,但是各个页面都是单独独立的,并没有关联页面跳转,而本篇文章的任务就是实现各个页面见的跳转。
要实现页面跳转,需要使用Navigation
,看到这个API
,大家是不是感觉有点熟悉,对的,其实这个就是我们在传统View
体系中用到的的Navigation
。在Compose
中,JetPack
中的很多库都对Compose
进行了适配,包括本文的Navigation
。
首先,我们需要在Gradle
中添加相关依赖
def nav_version = "2.5.2"
//implementation "androidx.navigation:navigation-fragment:$nav_version"
//implementation "androidx.navigation:navigation-ui:$nav_version"
implementation "androidx.navigation:navigation-compose:$nav_version"
NavHost
用来配置页面的路由URL
,需要传入NavController
。
NavController
是导航的管理者,内部维护着页面跳转过程的返回栈。
通过调用navController.navigate("路由URL")
来跳转到具体的页面。
我们在MainActivity
中新建名叫AppNavigation
的Composable
函数,用作创建NavHost
然后修改MainActivity
的setContent
为AppNavigation
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//沉浸式状态栏
WindowCompat.setDecorFitsSystemWindows(window, false)
val controller = WindowCompat.getInsetsController(window, window.decorView)
controller?.isAppearanceLightStatusBars = true
setContent {
BloomTheme {
AppNavigation()
}
}
}
@Composable
private fun AppNavigation() {
val navController = rememberNavController()
NavHost(navController = navController) {
}
}
}
通过NavHost
的startDestination
,我们可以设置默认跳转的页面
我们这里定义了WelcomePage
路由为welcome
,并通过将startDestination
设置为welcome
,使其成为App
默认启动的Compose
页面
WelcomePage
传入了navController
NavHost(navController = navController, startDestination = "welcome") {
composable("welcome") {
WelcomePage(navController)
}
}
这里将NavController传入了子Composable
其实更好的方式是子Composable通过回调操作NavController
跳转逻辑放在一起会更清晰,也方便单元测试
首先需要在NavHost
中再添加登录页,路由我这里取为login
NavHost(navController = navController, startDestination = "welcome") {
composable("welcome") {
WelcomePage(navController)
}
composable("login") {
LoginPage(navController)
}
}
然后,在WelcomePage
中,点击login
按钮的时候,调用navController.navigate("login")
,路由传的是login
,即会跳转到登录页面了。
TextButton(onClick = {
navController.navigate("login")
}, modifier = Modifier.padding(16.dp)) {
Text(
text = "Log in",
style = button,
color = pink900)
}
我们来看下怎么传递参数,以登录页面跳转到主页为例,我们希望传入用户ID
到主页。
首先我们在NavHost
中定义HomePage
的路由为userId
composable("home") { backStackEntry ->
HomePage(navController)
}
然后怎么获取userId
呢 ? 需要修改下路由为home/{userId}
,这个的参数需要用大括号{}
包裹
composable("home/{useId}")
这里设置的传递类型是String
,所以通过getString
获取
backStackEntry.arguments?.getString("userId")
默认情况下传递类型就是String
再来看一下完整的主页路由配置的代码
composable("home/{userId}") { backStackEntry ->
HomePage(navController, backStackEntry.arguments?.getString("userId"))
navArgument("userId") {
type = NavType.StringType //设置传递类型为String
}
}
接着,在登录页,点击登录按钮的时候,跳转该路由就可以了
Button(
onClick = {
navController.navigate("home/123")
}, modifier = Modifier
.padding(horizontal = 16.dp, vertical = 16.dp)
.height(48.dp)
.fillMaxWidth()
.clip(medium),
colors = ButtonDefaults.buttonColors(backgroundColor = pink900)
) {
Text(text = "Log in", style = button, color = white)
}
在主页上,我们打印下userId
,可以看到显示结果为 userId:123
@Composable
fun HomePage(navController: NavHostController, userId: String?) {
Log.i("HomePage", "userId:$userId")
//省略...
}
至此,我们就完成了Compose页面间跳转的功能
Compose 项目实战 系列文章
Android Compose Bloom 项目实战 (一) : 项目说明与配置
Android Compose Bloom 项目实战 (二) : 欢迎页
Android Compose Bloom 项目实战 (三) : 登录页
Android Compose Bloom 项目实战 (四) : 主页
本文源码 : ComposeBloom