现在跨平台开发框架有很多,比如H5类型,RN,Flutter等,而Kotlin多平台+Compose跨平台ui可能也是未来一种好用的开发框架
ps:后文KMM都是指Kotlin多平台框架,而不是单指Kotlin Multiplatform Mobile
虽然目前KMM还有些不太成熟,Compose跨平台的支持平台不太全,但也不妨碍现在来尝尝鲜.
ps:Compose-android正式,Compose-desktop正式,Compose-web未正式,Compose-ios期待中...
首先我们使用idea来创建一个KMM+Compose的原始框架项目
我们先将idea更新到最新(如果不想下载idea可以在文末下载示例的源码)
然后:File->New->Project
然后设置一下安卓sdk位置,点完成
创建好项目可以选择使用Android Studio或idea编写代码
idea,先同步一下gradle:
as,一般会自动同步gradle,手动如下:
我们可以看到有三个主要的开发目录:
android目录内其实就是一个安卓项目
desktop目录是一个jvm程序目录,运行其中的main函数,会出现一个GUI(也就是compose-desktop的程序),其中的程序目前是运行在一个精简版的jvm虚拟机中(打出来的包就带有精简版的jvm虚拟机,所以不依赖jvm环境),据说会有直接转成native的能力(目前不清楚有没有)
common目录是kmm的核心目录,可以看到其中有androidMain,commonMain,desktopMain等目录
commonMain是共享代码目录,只能调用kotlin基础库和多平台的三方库能力(比如compose,ktor等)
由于commonMain并不隶属于特定平台,所以只能交由 androidMain 和 desktopMain 来实现特定的平台能力(后面会看到示例)
common目录相对于android目录,相当于是安卓项目的一个library
common目录相对于desktop目录,相当于是jvm项目的一个library
ps:由于目前两个平台都是基于jvm的,所以commonMain目录也可以使用jvm基础库(File等)
基于多平台的comopse框架,我们可以直接在commonMain中写compose代码,在android和desktop中都可以调用:
我们看一下App.kt中的getPlatformName()函数,可以发现他是这样声明的:
这个相当于在共享模块声明它的签名,然后我们可以在每个平台中进行实现
androidMain目录中该函数的实现(desktopMain中实现也是这样):
这样我们就拥有了多平台开发能力,只要将平台间不兼容的地方声明一个待实现的多平台函数,然后在每个平台实现,就可以在commonMain中轻松使用了
接下来我们就去写一个简单的程序
我们要实现的ui如下,非常简单:
代码如下:
package com.lt.kmm_and_compose_sample.common
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
/**
* creator: lt 2022/3/15 [email protected]
* effect : 简单的根据数量放置list的条目
* warning:
*/
@Composable
fun NumberList() {
//设置数量的状态对象(State)
var number by remember { mutableStateOf(5) }
//相当于竖向的线性布局
Column {
//相当于横向的线性布局
Row {
//设置一个按钮
Button({
//按钮的点击事件,点击后改变状态对象内的值,会引发使用该对象的compose组件重组
number++
}) {
//设置按钮内的组件ui
Text("数量+1")
}
//设置一个宽度为8dp的占位,相当于将他们两个隔开了一点(就像margin)
Spacer(Modifier.width(8.dp))
Button({
number--
}) {
Text("数量-1")
}
Spacer(Modifier.width(8.dp))
Text("总数量:$number")
}
Spacer(Modifier.height(8.dp))
//相当于竖向的RecyclerView
LazyColumn {
//相当于RecyclerView.Adapter,只不过更简单
items(number) {
//设置item的ui
Item(it)
}
}
}
}
@Composable
fun Item(index: Int) {
//我们的item的ui中只有一个文字,并且设置了一下padding
Text("索引为:$index", modifier = Modifier.padding(5.dp))
}
我们把android文件夹中的MainActivity给App()代码注掉,然后使用我们刚写的compose代码
运行安卓项目后,点击数量+1,总数量文字会变,而且条目也会多一个
然后我们再修改一下desktop文件夹中的Main.kt
然后运行这个main函数看一下compose-desktop的效果(LazyColumn的滚动是滚动鼠标滚轮)
首先我们在commonMain的platform.kt文件中定义一下expect fun:
然后我们在androidMain和desktopMain中实现一下这个函数,为了简单就直接写死一个数了,
然后我们稍微改一下ui:
在 Text("总数量:$number") 下面增加如下代码:
ps:调用多平台函数可能没有代码提示emmm
Button({
number = getNumber()
}) {
Text("从本地加载数量")
}
然后一个简单的多平台应用就搞好了,后面有时间再写更复杂的功能
源码: ltttttttttttt/KMM_and_Compose_Sample
end