Compose Multiplatform 之旅—跳转、导航(Voyager)

在Android 开发的过程中,页面跳转常常是Activity或Fragment 之间进行切换,但是Compose MultiPlatform 没有这些东西了呀,那是如何跳转的呢?难不成自己去控制没有UI的显隐来实现这种跳转导航逻辑吗?

想了解更多Compose Multiplatform项目的小伙伴,可以看看之前的文章

找到合适的框架

看着这个问题,第一反应是不是有现成的库可以使用。首先看看官方,看到官方是有一个navigation 库,对应到Compose MultiPlatform项目是org.jetbrains.androidx.navigation ,但是目前是alpha版本,测试发现Android 和 iOS运行没有问题,但桌面端运行会有崩溃。所有先看看有没有三方成熟的框架。

这里推荐一下 klibs.io ,可以快速找到Kotlin Multiplatform 相关的三方库,比如我搜索navigation发现有两个库 VoyagerDecompose 相对来说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框架,后续我们可以一起接着分析。

相关推荐
哲科软件3 小时前
跨平台开发的抉择:Flutter vs 原生安卓(Kotlin)的优劣对比与选型建议
android·flutter·kotlin
jyan_敬言9 小时前
【C++】string类(二)相关接口介绍及其使用
android·开发语言·c++·青少年编程·visual studio
程序员老刘10 小时前
Android 16开发者全解读
android·flutter·客户端
福柯柯11 小时前
Android ContentProvider的使用
android·contenprovider
不想迷路的小男孩11 小时前
Android Studio 中Palette跟Component Tree面板消失怎么恢复正常
android·ide·android studio
餐桌上的王子11 小时前
Android 构建可管理生命周期的应用(一)
android
菠萝加点糖11 小时前
Android Camera2 + OpenGL离屏渲染示例
android·opengl·camera
用户20187928316711 小时前
🌟 童话:四大Context徽章诞生记
android
yzpyzp11 小时前
Android studio在点击运行按钮时执行过程中输出的compileDebugKotlin 这个任务是由gradle执行的吗
android·gradle·android studio
aningxiaoxixi11 小时前
安卓之service
android