KMM+Compose 开发一个Kotlin多平台应用
前言
現(xiàn)在跨平臺(tái)開發(fā)框架有很多,比如H5類型,RN,Flutter等,而Kotlin多平臺(tái)+Compose跨平臺(tái)ui可能也是未來(lái)一種好用的開發(fā)框架
ps:后文KMM都是指Kotlin多平臺(tái)框架,而不是單指Kotlin Multiplatform Mobile
雖然目前KMM還有些不太成熟,Compose跨平臺(tái)的支持平臺(tái)不太全,但也不妨礙現(xiàn)在來(lái)嘗嘗鮮.
ps:Compose-android正式,Compose-desktop正式,Compose-web未正式,Compose-ios期待中...
項(xiàng)目創(chuàng)建和結(jié)構(gòu)分析
首先我們使用idea來(lái)創(chuàng)建一個(gè)KMM+Compose的原始框架項(xiàng)目
我們先將idea更新到最新(如果不想下載idea可以在文末下載示例的源碼)
然后:File->New->Project
然后設(shè)置一下安卓sdk位置,點(diǎn)完成
?創(chuàng)建好項(xiàng)目可以選擇使用Android Studio或idea編寫代碼
idea,先同步一下gradle:
?as,一般會(huì)自動(dòng)同步gradle,手動(dòng)如下:
我們可以看到有三個(gè)主要的開發(fā)目錄:
android目錄內(nèi)其實(shí)就是一個(gè)安卓項(xiàng)目
desktop目錄是一個(gè)jvm程序目錄,運(yùn)行其中的main函數(shù),會(huì)出現(xiàn)一個(gè)GUI(也就是compose-desktop的程序),其中的程序目前是運(yùn)行在一個(gè)精簡(jiǎn)版的jvm虛擬機(jī)中(打出來(lái)的包就帶有精簡(jiǎn)版的jvm虛擬機(jī),所以不依賴jvm環(huán)境),據(jù)說會(huì)有直接轉(zhuǎn)成native的能力(目前不清楚有沒有)
common目錄是kmm的核心目錄,可以看到其中有androidMain,commonMain,desktopMain等目錄
commonMain是共享代碼目錄,只能調(diào)用kotlin基礎(chǔ)庫(kù)和多平臺(tái)的三方庫(kù)能力(比如compose,ktor等)
由于commonMain并不隸屬于特定平臺(tái),所以只能交由 androidMain 和 desktopMain 來(lái)實(shí)現(xiàn)特定的平臺(tái)能力(后面會(huì)看到示例)
common目錄相對(duì)于android目錄,相當(dāng)于是安卓項(xiàng)目的一個(gè)library
common目錄相對(duì)于desktop目錄,相當(dāng)于是jvm項(xiàng)目的一個(gè)library
ps:由于目前兩個(gè)平臺(tái)都是基于jvm的,所以commonMain目錄也可以使用jvm基礎(chǔ)庫(kù)(File等)
多平臺(tái)的三方庫(kù)
?基于多平臺(tái)的comopse框架,我們可以直接在commonMain中寫compose代碼,在android和desktop中都可以調(diào)用:
?KMM多平臺(tái)能力
我們看一下App.kt中的getPlatformName()函數(shù),可以發(fā)現(xiàn)他是這樣聲明的:
?這個(gè)相當(dāng)于在共享模塊聲明它的簽名,然后我們可以在每個(gè)平臺(tái)中進(jìn)行實(shí)現(xiàn)
androidMain目錄中該函數(shù)的實(shí)現(xiàn)(desktopMain中實(shí)現(xiàn)也是這樣):
這樣我們就擁有了多平臺(tái)開發(fā)能力,只要將平臺(tái)間不兼容的地方聲明一個(gè)待實(shí)現(xiàn)的多平臺(tái)函數(shù),然后在每個(gè)平臺(tái)實(shí)現(xiàn),就可以在commonMain中輕松使用了
?接下來(lái)我們就去寫一個(gè)簡(jiǎn)單的程序
正文
compose寫ui
我們要實(shí)現(xiàn)的ui如下,非常簡(jiǎn)單:
?
代碼如下:
package com.lt.kmm_and_compose_sample.commonimport 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 lt.dygzs@qq.com* effect : 簡(jiǎn)單的根據(jù)數(shù)量放置list的條目* warning:*/ @Composable fun NumberList() {//設(shè)置數(shù)量的狀態(tài)對(duì)象(State)var number by remember { mutableStateOf(5) }//相當(dāng)于豎向的線性布局Column {//相當(dāng)于橫向的線性布局Row {//設(shè)置一個(gè)按鈕Button({//按鈕的點(diǎn)擊事件,點(diǎn)擊后改變狀態(tài)對(duì)象內(nèi)的值,會(huì)引發(fā)使用該對(duì)象的compose組件重組number++}) {//設(shè)置按鈕內(nèi)的組件uiText("數(shù)量+1")}//設(shè)置一個(gè)寬度為8dp的占位,相當(dāng)于將他們兩個(gè)隔開了一點(diǎn)(就像margin)Spacer(Modifier.width(8.dp))Button({number--}) {Text("數(shù)量-1")}Spacer(Modifier.width(8.dp))Text("總數(shù)量:$number")}Spacer(Modifier.height(8.dp))//相當(dāng)于豎向的RecyclerViewLazyColumn {//相當(dāng)于RecyclerView.Adapter,只不過更簡(jiǎn)單items(number) {//設(shè)置item的uiItem(it)}}} }@Composable fun Item(index: Int) {//我們的item的ui中只有一個(gè)文字,并且設(shè)置了一下paddingText("索引為:$index", modifier = Modifier.padding(5.dp)) }我們把a(bǔ)ndroid文件夾中的MainActivity給App()代碼注掉,然后使用我們剛寫的compose代碼
?運(yùn)行安卓項(xiàng)目后,點(diǎn)擊數(shù)量+1,總數(shù)量文字會(huì)變,而且條目也會(huì)多一個(gè)
然后我們?cè)傩薷囊幌耫esktop文件夾中的Main.kt
然后運(yùn)行這個(gè)main函數(shù)看一下compose-desktop的效果(LazyColumn的滾動(dòng)是滾動(dòng)鼠標(biāo)滾輪)
使用KMM多平臺(tái)方法
首先我們?cè)赾ommonMain的platform.kt文件中定義一下expect fun:
然后我們?cè)赼ndroidMain和desktopMain中實(shí)現(xiàn)一下這個(gè)函數(shù),為了簡(jiǎn)單就直接寫死一個(gè)數(shù)了,?
然后我們稍微改一下ui:
在 Text("總數(shù)量:$number") 下面增加如下代碼:
ps:調(diào)用多平臺(tái)函數(shù)可能沒有代碼提示emmm
Button({number = getNumber()}) {Text("從本地加載數(shù)量")}?然后一個(gè)簡(jiǎn)單的多平臺(tái)應(yīng)用就搞好了,后面有時(shí)間再寫更復(fù)雜的功能
源碼:?ltttttttttttt/KMM_and_Compose_Sample
end
總結(jié)
以上是生活随笔為你收集整理的KMM+Compose 开发一个Kotlin多平台应用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用Kotlin写脚本
- 下一篇: KMM Kotlin expect的几种