前段时间学习了一下 KMP (Kotlin Multiplatform) 和 CMP (Compose Multiplatform),在学习和尝试的过程中发现了 CMP 在 iOS 上的一个 bug,经过一些调查确定了问题的原因和解决方案。尝试将 bugfix 的代码提交 PR 给官方的仓库,被 review 通过并合并进了主分支,预计将会 已于2026年6月16日在 1.12.0-alpha02 中被首次发布。
虽然是一个很简单的内容,但是在发现、修改和提交的过程中对于 CMP 在非 Android 平台的实现、项目的组织架构和面向开源社区的修改流程都有了一些更深的了解;这里简单分享一下这个问题发现、解决、测试、提交和被官方接受合并的全流程。
有关 KMP/CMP 使用体验,再使用一段时间后再做单独的分享吧。简单来说,给了 Android 开发者一种可以通过更加熟悉的语言/技术栈实现跨平台构建应用的方式。
背景和问题描述
在学习 KMP/CMP 时,通过 CMP 自带的第一方库 Material 直接构建 Material 3 的 UI 时,发现一个问题,DatePickerDialog 的 confirmButton 和 dismissButton 两个槽位在 iOS 设备上显示的顺序与同平台的 TimePickerDialog 不一致,与 Android 上的两种 Dialog 显示也不一致。根据 Material Design 设计规范 (https://m3.material.io/components/date-pickers/overview )认为这个实现有问题;在LTR 语言下,confirmButton 应该显示在右侧, dismissButton应该显示在左侧。
通过搜索发现已经有人汇报此问题:https://youtrack.jetbrains.com/issue/CMP-10091/iOS-Material3-dialogs-render-confirmButton-and-dismissButton-in-inconsistent-positions
问题定位和寻找解决方案
因为 CMP 是基于 Google 的 Jetpack Compose 扩展的, Android 上的显示没有问题即 Jetpack Compose没有问题,所以去 Jetpack Compose (androidx) 仓库查看 Android 上的实现。
通过包名定位到文件 https://github.com/androidx/androidx/commits/androidx-main/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/DatePickerDialog.android.kt 并查看实现,并确认其修改历史记录。可以看到 Jetpack Compose 在这个提交中修复了这个问题: https://github.com/androidx/androidx/commit/5e5fbccd7244ff97245f48d500dd4dcf0f420e4c
在 Android 之外的其它平台(iOS,Desktop, Kotlin/JS 和 Kotlin/Wasm),CMP 是通过 Skia 绘制的画面。基本定位是 https://github.com/JetBrains/compose-multiplatform-core/blob/jb-main/compose/material3/material3/src/skikoMain/kotlin/androidx/compose/material3/DatePickerDialog.skiko.kt 的问题。对比与 Android 平台的实现,确认其两个槽位的调用顺序相反。 参照 Jetpack Compose 的修改方法进行了修改。
测试和提交
因为问题是 Skia 相关的,所以相关的实现没有在 Jetpack Compose (androidx/androidx) 的仓库中,是在 JetBrains/compose-multiplatform-core 仓库中。所以修改应该提交到这个仓库。
Fork 一下 compose-multiplatform-core ,然后 clone 到本地并使用 Android studio 打开。
做修改之后点开右侧工具栏 gradle 图标,找到 compose/material3/material3/publishing, 有一个任务叫 publishToMavenLocal 双击运行
会将对应的内容发布到本地的 maven(在 /Users/用户名/.m2/repository 目录下),默认版本号 9999.0.0-SNAPSHOT。
在使用 CMP 项目中修改 settings.gradle.kts ,将 mavenLocal() 添加到 repositories 块中最前方,然后修改对应组件的依赖版本为 9999.0.0-SNAPSHOT 并重新构建项目。
运行在受影响的平台上,确认修改已经完成。
创建一个分支并提交修改,然后推送到自己 Fork 仓库的远端。
查看 compose-multiplatform 的 contributing: https://github.com/JetBrains/compose-multiplatform/blob/master/CONTRIBUTING.md 并按照步骤签署谷歌的代码贡献协议。并按照流程完成对应的 Check/CI 等。
创建PR:https://github.com/JetBrains/compose-multiplatform-core/pull/3048 描述相关内容。
然后就是等待了。在 2026年5月18日 收到两名维护者的 Review Approve之后,修改于 5月19日 被合并到 JetBrains:jb-main 分支中。这个时候如果看项目的首页,就能看到头像了。

在问题关联的 YouTrack 可以看到 Target Versions 被修改为 1.12.0-alpha02。按照发布节奏,再陆续经过若干 alpha、beta 和 RC 版本之后,预计就可以顺利被发布到 1.12.0 版本中了。