完整案例:Kotlin+Compose+Multiplatform 跨平台之桌面端实现(二)
本文是 Kotlin+Compose+Multiplatform 跨平台桌面端开发系列的第二篇,将深入实际开发内容。在前一篇文章介绍了基础工程、配置、打包和布局的基础上,本篇涵盖以下核心主题:自定义标题栏与窗口控制、换肤功能实现、ViewModel 在桌面端的应用、网络与文件操作、多页面切换与路由管理、文件选择对话框以及 KV 存储的使用。
一、自定义标题栏与窗口控制
在桌面端应用中,自定义标题栏需要先隐藏系统默认标题栏,通过将 Window 的 undecorated 属性设置为 true 来实现。窗口的最小尺寸可通过 window.minimumSize 进行设置。窗口的最大化、恢复、最小化和关闭操作分别对应以下代码:
- 最大化:
window.placement = WindowPlacement.Maximized - 恢复浮动状态:
window.placement = WindowPlacement.Floating - 最小化:
windowState.isMinimized = true - 关闭:
ApplicationScope.exitApplication()
窗口拖动功能通过在自定义标题栏外层包裹 WindowDraggableArea 实现,例如:
scope.WindowDraggableArea(Modifier.fillMaxWidth().height(40.dp)) {
// 自定义标题栏内容
}
二、换肤功能实现
换肤通过动态更新 MaterialTheme 的 colorScheme 来实现。首先,定义一个主题管理器,使用 mutableStateOf 来管理当前皮肤主题,确保主题更改时 Compose 界面重组。皮肤主题索引通过 KV 存储保存在本地,以便应用重启后恢复。
示例主题管理器代码如下:
object ThemeManager {
var skinThemeType by mutableStateOf(PlatformKVStore.getSkinType())
var skinTheme by mutableStateOf(getColorsSchemes(skinThemeType))
private fun getColorsSchemes(skinType: Int) = when (skinType) {
0 -> LightColors
1 -> DarkColors
// 其他皮肤定义
else -> LightColors
}
}
切换皮肤时,更新 skinTheme 并保存索引:PlatformKVStore.saveSkin(it) 和 ThemeManager.skinTheme = item。
三、ViewModel 在桌面端的应用
使用第三方库 moe.tlaster:precompose 和 moe.tlaster:precompose-viewmodel(版本 ≥1.6.2)在桌面端实现类似 Android 的 ViewModel。在 jvmMain.dependencies 中添加依赖后,该库支持 Windows 和 macOS,与 ViewModel 和 MVI 架构深度集成,简化状态管理,并兼容协程,适合跨平台项目。
四、网络与文件操作
由于 Compose 桌面端基于 JVM,网络请求可直接使用 OkHttp 和 Retrofit,文件操作也可沿用 Android 的 IO 相关库和写法,确保了代码的复用性和一致性。
五、多页面切换与路由管理
页面切换可以通过 Compose 的 Tab 结合 VerticalPager 或 HorizontalPager 实现,或使用 NavHost 进行路由管理。对于深层页面导航,推荐使用 moe.tlaster:precompose 中的路由功能。示例路由配置如下:
@Composable
fun NavGraph() {
val navigator = rememberNavigator("key222222")
NavHost(
navigator = navigator,
initialRoute = RouterUrls.news_first
) {
scene(RouterUrls.news_first) {
// 第一个页面
}
scene(RouterUrls.news_second) { backStackEntry ->
// 第二个页面,支持参数传递
}
}
}
路由设计应简化,仅对需要多层导航的页面使用路由,平行标签页可用分页器实现。
六、文件选择对话框
桌面端原生提供 JFileChooser 用于文件选择。通过设置 fileSelectionMode 参数,可以限制用户选择类型:
JFileChooser.DIRECTORIES_ONLY:仅选择目录JFileChooser.FILES_ONLY:仅选择文件JFileChooser.FILES_AND_DIRECTORIES:文件和目录均可选
示例代码:
JFileChooser(PlatformKVStore.getDownloadDir()).apply {
fileSelectionMode = JFileChooser.DIRECTORIES_ONLY
if (showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
val selectedDir = selectedFile.absolutePath
_downloadPath.value = selectedDir
PlatformKVStore.saveDownloadDir(selectedDir)
}
}
七、KV 存储使用
使用 com.russhwolf:multiplatform-settings 库实现跨平台 KV 存储,支持 Android、iOS、macOS、JVM 和 Windows 等平台。用法简单,例如存储和读取整型数据:
val settings = Settings()
settings.putInt("count", 5) // 存储
val value = settings.getInt("count", 0) // 读取,带默认值
总结
本文详细介绍了 Kotlin+Compose+Multiplatform 在桌面端开发中的关键实践,包括自定义标题栏、换肤、ViewModel 使用、网络与文件操作、路由管理、文件选择以及 KV 存储。这些内容为构建功能完整的跨平台桌面应用提供了实用指导。后续文章将涵盖数据库使用、音乐播放和视频播放等高级主题。