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框架,后续我们可以一起接着分析。

相关推荐
人生游戏牛马NPC1号42 分钟前
学习 Flutter (一)
android·学习·flutter
fundroid2 小时前
Swift 进军 Android,Kotlin 该如何应对?
android·ios
前端世界2 小时前
鸿蒙系统安全机制全解:安全启动 + 沙箱 + 动态权限实战落地指南
android·安全·harmonyos
_一条咸鱼_4 小时前
Vulkan入门教程:源码级解析
android·面试·android jetpack
嘉小华4 小时前
ThreadLocal 详解
android
wkj0015 小时前
php 如何通过mysqli操作数据库?
android·数据库·php
kymjs张涛6 小时前
零一开源|前沿技术周报 #7
android·前端·ios
wuwu_q8 小时前
RK3566/RK3568 Android11 修改selinux模式
android·rk3568
_一条咸鱼_9 小时前
Android Runtime内存共享与访问控制原理剖析(71)
android·面试·android jetpack
嘉小华9 小时前
第三章:焦点分发全链路源码解析
android