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

相关推荐
每次的天空2 小时前
Android第二次面试总结(项目拷打实战)
android
&有梦想的咸鱼&2 小时前
Android Dagger2 框架辅助工具模块深度剖析(六)
android
tangweiguo030519873 小时前
Android 全屏6位密码输入框:优化布局与功能实现
android·nginx
二流小码农4 小时前
鸿蒙开发:权限管理之授权方式
android·ios·harmonyos
每次的天空4 小时前
kotlin中的行为组件
android·开发语言·kotlin
wangz764 小时前
Kotlin,jetpack compose,Android,MPAndroidChart,折线图示例
android·kotlin·mpandroidchart
二流小码农5 小时前
鸿蒙开发:申请授权权限
android·ios·harmonyos
锋风5 小时前
音视频缓存数学模型
android
_一条咸鱼_5 小时前
深入剖析 Android Dagger 2 框架的注解模块(一)
android
小白马丶5 小时前
Jetpack源码解读(二)——LiveData
android·android jetpack