最近, Android 开发已经相当现代化, 大量的 XML 布局已经被关闭, 这正是 Jetpack Compose(Android 的现代化, 完全声明式 UI 工具包)的时代. 凭借其强大而直观的基于 Kotlin 的语法, Compose 简化了UI开发, 同时也为未来更简洁, 更反应灵敏, 更动态的移动应用打开了大门.
Jetpack Compose 得到了开发人员的广泛采用和认可. 与此同时, 跨平台解决方案的需求也在不断增长. 因此, 作为 Kotlin 背后的强大力量, JetBrains 与谷歌携手将 Compose 体验扩展到更跨平台, Compose Multiplatform 应运而生.
有了这个UI框架, 你就可以将 Kotlin Multiplatform 的代码共享功能扩展到应用逻辑之外. 你可以一次性实现UI, 然后将其用于所有目标平台(iOS, Android, 桌面).
在本教程中, 我创建了一个带有自定义数据的懒列示例应用, 可在 Android, iOS 和桌面(对我来说是 Mac)上运行. 为创建UI, 你将使用 Compose Multiplatform 框架并学习其基础知识: Composable, 主题, 布局, 事件和Modifier.
支持的平台有:

现在的问题是, Kotlin Multiplatform 和 Compose Multiplatform 之间有什么区别?
Kotlin Multiplatform 是用于在平台间共享业务逻辑的工具, 但它有一个很大的缺点 — 开发人员仍需使用**Jetpack Compose(Android)和SwiftUI(iOS)**等本地工具来实现UI.
在此, Compose Multiplatform登场, 填补了KMP的空白, 完善了 Kotlin 体验. 通过将Compose和KMP结合起来, 你可以根据项目的复杂程度, 使代码库中 80%-95% 的内容由 Kotlin 构成. 对于我这个 Android 开发人员来说, 这听起来相当令人兴奋.
简而言之, 两者的区别在于
Kotlin Multiplatform – 仅共享业务逻辑 + 单独的 Android 和 iOS UI
Compose Multiplatform – 共享业务逻辑 + Android 和 iOS 共享UI
那么哪个更好呢? 很明显, Compose 跨平台:

深度实现
首先, 你需要一台用于跨平台开发的工作机. 不久之后, 你将需要安装了KMP插件, Xcode和CocoaPods依赖管理器的Android Studio.
好消息是, 你甚至不需要花时间进行适当的KMP + Compose项目设置, JetBrains提供了一个便捷模板, 其中包含对该模板中发生的事情的逐步解释, 你可以在该模板中选择平台并下载, 它会为你创建一个示例项目设置.
让我解释一下项目结构是怎样的:

- composeApp- 它包含平台特定文件夹, 其中包含入口点, 共享UI和业务逻辑
- commonMain – 在这个模块中, 我们将保留所有共享的 Compose UI 和业务逻辑
- androidMain – Kotlin 模块, Android 应用的入口点, 包含平台特定的类, 如 Application 和 Activity, 以及所需的其他依赖项.
- desktopMain – Kotlin 模块, 桌面应用的入口点, 包含平台特定的类, 如 Window 类.
- iosMain – 包含特定平台配置和类的 Xcode 项目. 在构建过程中, commonMain 模块会作为 CocoaPod 依赖项捆绑到 iOS 项目中.
让我们看看如何定义每个平台的依赖关系和平台间的共同依赖关系.
在 Gradle 文件夹中, 我们有版本目录文件:
[versions]
agp = "8.1.4"
android-compileSdk = "34"
android-minSdk = "24"
android-targetSdk = "34"
androidx-activityCompose = "1.8.2"
androidx-appcompat = "1.6.1"
androidx-constraintlayout = "2.1.4"
androidx-core-ktx = "1.12.0"
androidx-espresso-core = "3.5.1"
androidx-material = "1.10.0"
androidx-test-junit = "1.1.5"
compose = "1.5.4"
compose-compiler = "1.5.6"
compose-plugin = "1.5.11"
junit = "4.13.2"
kotlin = "1.9.21"
ktor = "2.3.7"
coroutines = "1.7.3"
[libraries]
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activityCompose" }
compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose" }
compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "compose" }
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
ktor-client-okhttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" }
ktor-client-darwin = { module = "io.ktor:ktor-client-darwin", version.ref = "ktor" }
ktor-client-cio= {module ="io.ktor:ktor-client-cio", version.ref = "ktor"}
kotlin-serialization = {module = "io.ktor:ktor-serialization-kotlinx-json", version.ref="ktor"}
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }
kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "coroutines" }
[plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" }
androidLibrary = { id = "com.android.library", version.ref = "agp" }
jetbrainsCompose = { id = "org.jetbrains.compose", version.ref = "compose-plugin" }
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
kotlinSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
- [versions]- 带编号的版本名称
- [libraries]- 带有模块和版本号的库名[版本
- [plugins]- 带有 ID 和版本号的插件名称[版本
现在我们可以像这样在 build.gradle
中使用库:

项目级 build.gradle
的插件:

现在让我们快速回顾一下如何定义依赖关系:
sourceSets {
val desktopMain by getting
androidMain.dependencies {
implementation(libs.compose.ui.tooling.preview)
implementation(libs.androidx.activity.compose)
implementation(libs.ktor.client.okhttp)
implementation(libs.kotlinx.coroutines.android)
}
commonMain.dependencies {
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material)
implementation(compose.ui)
@OptIn(ExperimentalComposeLibrary::class)
implementation(compose.components.resources)
implementation(libs.ktor.client.core)
implementation(libs.kotlin.serialization)
implementation(libs.kotlinx.coroutines.core)
}
desktopMain.dependencies {
implementation(compose.desktop.currentOs)
implementation(libs.ktor.client.cio)
}
iosMain.dependencies {
implementation(libs.ktor.client.darwin)
}
}
- androidMain.dependencies — 用于 Android 特定的依赖关系
- iOSMain.dependencies — 用于 iOS 特定的依赖关系
- desktopMain.dependencies — 用于桌面特定的依赖关系
- commonMain.dependencies — 用于平台间的通用依赖关系
所有平台都有一个入口 App.kt
:
@Composable
fun App() {
MaterialTheme {
Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
ListScreen(Repository.getDataList())
}
}
}
@Composable
fun ListScreen(list: List<Products>)
{
LazyColumn(modifier = Modifier.fillMaxWidth(), contentPadding = PaddingValues(16.dp)) {
items(list) { data ->
ColumnItem(data.title, data.description, data.price.toString(), data.image)
}
}
}
@OptIn(ExperimentalResourceApi::class)
@Composable
fun ColumnItem(name: String, description: String, price:String, image: String) {
Card(
modifier = Modifier.padding(8.dp)
.fillMaxWidth()
.wrapContentHeight(),
shape = MaterialTheme.shapes.medium,
elevation = 5.dp,
backgroundColor = MaterialTheme.colors.surface
) {
Row(
verticalAlignment = Alignment.CenterVertically,
) {
Image(
painter = painterResource(res = "compose-multiplatform.xml"),
contentDescription = null,
modifier = Modifier.size(100.dp)
.padding(8.dp),
contentScale = ContentScale.Fit,
)
Column(Modifier.padding(4.dp)) {
Text(
modifier = Modifier.padding(2.dp),
text = name,
maxLines = 3,
style = MaterialTheme.typography.h6,
color = MaterialTheme.colors.onSurface,
)
Text(
modifier = Modifier.padding(2.dp),
text = description,
maxLines = 3,
style = MaterialTheme.typography.body2,
)
Text(
modifier = Modifier.padding(2.dp),
text = "Price USD $price",
style = MaterialTheme.typography.button,
)
}
}
}
}
让我们从顶部选择平台并运行应用, 就这样:


总结一下
- 我们学习了跨平台环境设置
- 我们学习了如何使用项目结构
- 我们学习了如何声明通用依赖和特定平台依赖
- 我们了解了如何在平台间共享UI
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.dandroid.cn/archives/22830,转载请注明出处。
评论0