使用 Compose 在 iOS 上实现灵动岛效果
The following article is from 程序员江同学 Author 程序员江同学
前言
在去年 DevFest 的 Compose Camp 活动上,fundroid 与朱江两位讲师带着大家使用 Compose 实现了灵动岛效果
但是灵动岛毕竟是 iOS 上的特性,正好今年 KotlinConf 上宣布了 Compose-iOS 已经 alpha 了,那么如果我们将已经用 Compose 实现的灵动岛效果,移植到 iOS 上又会怎么样呢?
想想多是一件美事啊,说干就干,看看把代码从 Jetpack Compose 迁移到 Compose Multiplatform 中到底要做什么工作,要付出什么成本
效果展示
首先看下效果,可以看到,基本实现了灵动岛切换的动画效果,与在 Android 上的效果也基本一致
实现步骤
环境配置
要使用 Compose MultiPlatform 开发,需要以下环境
XCode Android Studio Kotlin Multiplatform Mobile 插件 Cocoapods 依赖管理器
其实跟 Kotlin Multiplatform 所需要的环境一致,其中最麻烦的可能是 Cocoapods 的安装,可以查看 KMM 安装 Cocoapods 的文档:Set up an environment to work with CocoaPods
此外,你也可以通过kdoctor
命令来检查环境配置否正确
brew install kdoctor // 安装 kdoctor
kdoctor // 检查
如果所有环境都配置正确,你会看到以下输出
Environment diagnose (to see all details, use -v option):
[✓] Operation System
[✓] Java
[✓] Android Studio
[✓] Xcode
[✓] Cocoapods
Conclusion:
✓ Your system is ready for Kotlin Multiplatform Mobile development!
创建项目
Compose Multiplatform 项目其实就是在 KMM 项目中加入一些 Compose 的内容,还是有不少模板代码的,我们可以直接使用 JetBrains 提供的项目模板生成项目:compose-multiplatform-ios-android-template
如图所示,其实就是一个 KMM 工程的结构,android 项目的入口是 androidApp,iOS 项目的入口是 iosApp,共享代码放在 shared 模块
在 shared 模块中,各个平台共享代码放在 commonMain 目录中,而各个平台的定制代码则放在 androidMain 与 iosMain 中
在这里主要的不同在于,android 平台直接返回了一个 Composable 函数,供 android 层调用,而 iOS 平台则返回了一个 UIViewController
代码移植
在项目创建完成后,接下来就是代码移植的工作了。移植过程可以说是非常简单,基本上不用做任何改动,Jetpack Compose 项目就可以迁移成 Compose Multiplatform 项目
在我迁移过程中碰到的唯一不同在于资源文件的处理,如下所示,R 文件引用方式需要修改成字符串方式引用
// Jetpack Compose
Image(
painterResource(R.drawable.icon_cover),
"music cover",
Modifier
.size(animationData.musicImageSize)
.clip(RoundedCornerShape(animationData.musicImageCorner))
)
// Compose Multiplatform
Image(
painterResource("icon_cover.xml"),
"music cover",
Modifier
.size(animationData.musicImageSize)
.clip(RoundedCornerShape(animationData.musicImageCorner))
)
除此之外,两者的状态管理,布局,动画等 api 是完全一致的,可以直接复用代码
经过以上步骤,迁移就完成了,直接运行 androidApp 与 iosApp 就可以得到文章开始展示的效果了
正在处理中的问题
当然,现在 Compose Multiplatform 还处在 alpha 阶段,并不是说已经可以用于生产了,还有不少问题正在处理中
待支持的功能
图片来源:Compose Multiplatform on iOS by: Sebastian Aigner and Nikita Lipsky
可以看出,Compose Multiplatform 还是有不少细节问题要处理的
性能问题
我们打开 XCode 的 instruments 然后运行 app,就可以得到运行的 trace 文件,统计出运行次数较多或者比较耗时的方法
可以看出,耗时方法有相当一部分是 GC 相关的,当 GC 暂停发生时,会冻结所有对象,自然也会影响 UI 的渲染,导致卡顿
好消息是 Kotlin 正在优化 GC,期望将 GC 暂停控制在 1 到 2 ms 之内
总结
可以看出将 Jetpack Compose 版的灵动岛迁移到 Compose Multiplatform 的成本是非常低的,最耗时的部分可能是配环境的部分,两者的 API 基本上是一致的,因此代码可以无缝复用
Compose 跨平台补全了 Kotlin 跨平台只支持共享逻辑不支持共享 UI 的短板,降低了 Kotlin 跨平台的开发成本,总得来说,未来可期,希望 Jetbrains 能早日推出正式版
示例代码
本文所有代码可见:https://github.com/RicardoJiang/DynamicIsland
参考资料
Compose Multiplatform on iOS by: Sebastian Aigner and Nikita Lipsky
-- END --
推荐阅读