在Android 开发的过程中,页面跳转常常是Activity或Fragment 之间进行切换,但是Compose MultiPlatform 没有这些东西了呀,那是如何跳转的呢?难不成自己去控制没有UI的显隐来实现这种跳转导航逻辑吗?
想了解更多Compose Multiplatform项目的小伙伴,可以看看之前的文章
- Compose Multiplatform 之旅 --- 启程
- Compose Multiplatform 之旅 --- 项目初探
- Compose Multiplatform 之旅 ---做一个自己的项目(别踩白块)
- Compose Multiplatform 之旅---看看大佬在做啥
- Compose Multiplatform 之旅---为什么可以跨平台
- Compose Multiplatform 之旅---声明式UI
找到合适的框架
看着这个问题,第一反应是不是有现成的库可以使用。首先看看官方,看到官方是有一个navigation 库,对应到Compose MultiPlatform项目是org.jetbrains.androidx.navigation ,但是目前是alpha版本,测试发现Android 和 iOS运行没有问题,但桌面端运行会有崩溃。所有先看看有没有三方成熟的框架。
这里推荐一下 klibs.io ,可以快速找到Kotlin Multiplatform 相关的三方库,比如我搜索navigation发现有两个库 Voyager 和 Decompose 相对来说star 比较高。
使用GPT对比下了这个库,Voyager 更轻量级,更适合轻量级项目,star也更高,所有现阶段选择了Voyager。后续如果有需要,我们再来分析一下Decompose。
Voyager 使用
引入依赖
arduino
//在build.gradle.kts 的commonMain引入相关依赖
commonMain.dependencies {
...
implementation(libs.voyager.navigator) //基础跳转
implementation(libs.voyager.tab.navigator) //底导航相关
}
//libs.versions.toml 中定义版本号
voyagerNavigator = "1.1.0-beta03"
voyager-navigator = { module = "cafe.adriel.voyager:voyager-navigator", version.ref = "voyagerNavigator" }
voyager-tab-navigator = { module = "cafe.adriel.voyager:voyager-tab-navigator", version.ref = "voyagerNavigator" }
底Tab
要实现底tab,首先继承Tab,定义好几个页面。需要实现options 和 Content()
- TabOptions 是底Tab的样式定义 ,可以定义文案,图标样式
- Content 就是这个页面对应的内容,是一个Composable
kotlin
object HomeTab: Tab {
override val options: TabOptions
@Composable
get() = TabOptions(
index = 0u,
title = "Home"
)
@Composable
override fun Content() {
Text("首页")
}
}
按照上面的HomeTab定义,再实现一个FindTab和MineTab。在对应的APP入口定义好这些tabs。利用 BottomNavigation 组件结合 Voyager.Navigator,实现页面展示底部导航栏的切换。
ini
@Composable
@Preview
fun App() {
val tabs = remember { listOf(HomeTab, FindTab, MineTab) }
MaterialTheme {
TabNavigator(HomeTab) { tabNavigator ->
Scaffold(
bottomBar = {
BottomNavigation {
tabs.forEach { tab ->
val isSelected = tabNavigator.current == tab
BottomNavigationItem(
selected = isSelected,
onClick = { tabNavigator.current = tab},
icon = {
tab.options.icon
},
label = { Text(tab.options.title) }
)
}
}
}
) {
CurrentTab()
}
}
}
}
效果展示
页面跳转
每个页面在Voyager中对应一个Screen,只需要实现 Content() 方法,对应一个@Composable,就是这个页面的内容。 当跳转时,通过LocalNavigator.current获取到navigator。通过navigator的push方法 放入一个新的Screen,就能进入到这个新的Screen页面了,类似于Activity里面 的一个standard模式的任务栈。如果需要返回,就通过navigator的pop方法 出栈,就能实现返回了。
ini
class NowScreen : Screen {
@Composable
override fun Content() {
Column (
modifier = Modifier.fillMaxSize().background(Color.Yellow),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
){
val navigator = LocalNavigator.current
Text(
text = "当下",
fontSize = 20.sp,
color = Color.Black
)
Button(onClick = { navigator?.push(PastScreen()) }) {
Text("回到昨天")
}
Button(onClick = { navigator?.pop() }) {
Text("还能回去吗?")
}
}
}
}
我们先实现三个类似的过去、现在、未来三个Screen,下方一个按钮是跳转,一个按钮是返回。 然后在上面的首页HomeTab 的Content 中,通过Navigator放入这个页面,就可以实现跳转返回的效果了。
kotlin
object HomeTab: Tab {
override val options: TabOptions
@Composable
get() = TabOptions(
index = 0u,
title = "Home",
)
@Composable
override fun Content() {
Navigator(NowScreen())
}
}
效果展示
结语
通过Voyager我们就能快速实现多端的导航和跳转效果,Voyager还有一些动效、ViewModel的用法,以及上面说的Decompose框架,后续我们可以一起接着分析。