Compose Multiplatform 跨平臺(tái)體驗(yàn)

環(huán)境配置

首先在 Module 的 build.gradle.kts 文件中添加 compose 的依賴(lài)

plugins {
    kotlin("multiplatform")
    id("com.android.library")
    // 添加 compose 插件河质,
    // 這里為什么是 1.5.10,以為我使用的是 1.9.20 的 Kotlin
    // Kotlin 和 Compose 的版本對(duì)應(yīng)關(guān)系可見(jiàn)文末鏈接
    id("org.jetbrains.compose").version("1.5.10")
}

sourceSets {
    val commonMain by getting {
        dependencies {
            // compose
            api(compose.ui)
            api(compose.foundation)
            api(compose.material)
            api(compose.runtime)
        }
    }
}

添加完畢后染坯,sync 一下,提示需要將 compileSdkVersion 升級(jí)到 33丘逸,修改根目錄下的 build.gradle

ext {
    compileSdkVersion = 33
}

再次 sync单鹿,提示錯(cuò)誤警告:uikit還處于試驗(yàn)階段并且有許多bug,想要使用的話(huà)深纲,需要在 gradle.properties 添加一個(gè)配置項(xiàng)

##ERROR: Compose targets '[uikit]' are experimental and may have bugs!
##But, if you still want to use them, add to gradle.properties:
org.jetbrains.compose.experimental.uikit.enabled=true

至此仲锄,可以開(kāi)始嘗試使用 Compose 了

使用ComposeUI寫(xiě)界面

寫(xiě)了一個(gè)常見(jiàn)的列表分組樣式,更多 Compose 用法這里不做演示

// 必須添加這個(gè)注解
@Composable
fun AboutUsView(response: String, onItemClick: () -> Unit) {
    // 解析出列表數(shù)據(jù)
    val list = json.decodeFromString<List<AboutGroupItemBean>>(response)
    // 創(chuàng)建一個(gè)縱向布局
    Column {
        // LazyColumn 類(lèi)比 ListView
        LazyColumn {
            // 遍歷添加數(shù)據(jù)
            list.forEach { group ->
                // 添加一個(gè)組數(shù)據(jù)湃鹊,這里寫(xiě)的是一個(gè)分割線(xiàn)
                item {
                    // 自定義的 Composable 函數(shù)
                    SHDivider()
                }
                val groupItem = group.groupItem
                groupItem?.let {
                    // 繼續(xù)遍歷 group 中的列表數(shù)據(jù)
                    itemsIndexed(it) { index, item ->
                        Column {
                            // 只有非第一行數(shù)據(jù)儒喊,才有分割線(xiàn)
                            if (index != 0) {
                                SHDivider(1.dp)
                            }
                            val title = item["title"]
                            // 單條數(shù)據(jù)
                            SHListItem(title, onItemClick)
                        }
                    }
                }
            }
        }
    }
}
 
 
 
// 自定義的分割線(xiàn)
@Composable
fun SHDivider(height: Dp = 10.dp) {
    Divider(
            modifier = Modifier.height(height),
            color = Color(0xFFFAFAFB)
    )
}
 
// 自定義的列表數(shù)據(jù)
@Composable
fun SHListItem(title: String?, onItemClick: () -> Unit) {
    if (!title.isNullOrEmpty()) {
        Box(
                modifier = Modifier
                        .fillMaxWidth()
                        .height(44.dp)
                        .clickable(onClick = onItemClick)
                        .background(Color.White),
                contentAlignment = Alignment.CenterStart
        ) {
            Row(
                    horizontalArrangement = Arrangement.SpaceBetween,
                    modifier = Modifier.fillMaxWidth()
            ) {
                Text(
                        text = title,
                        fontSize = 14.sp,
                        color = Color(0xFF333333),
                        modifier = Modifier.padding(start = 15.dp)
                )
                Text(
                        text = "箭頭",
                        modifier = Modifier.padding(end = 15.dp)
                )
            }
        }
    }
}


遇到的問(wèn)題

加載本地圖片

使用 Compose 加載本地圖片代碼如下

Image(
        painter = painterResource(res: String),
        contentDescription = null,
)

但是上述導(dǎo)入的依賴(lài)庫(kù)中并沒(méi)有 painterResource 函數(shù),故需要添加新的依賴(lài)币呵,代碼如下

sourceSets {
    val commonMain by getting {
        dependencies {
            ...
            // 解決 compose-ui 資源加載問(wèn)題
            @OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class)
            implementation(compose.components.resources)
        }
    }
}

這里有個(gè)問(wèn)題澄惊,compose.components.resources 接入時(shí),需要添加 @OptIn 注解,注解的意思為:這是一個(gè)試驗(yàn)中的庫(kù)掸驱,說(shuō)明還不能用在生產(chǎn)包中肛搬,只能用于嘗鮮
看了 painterResource 的源碼,也有著大大 TODO 注釋?zhuān)f(shuō)未來(lái)這個(gè) API 會(huì)改變毕贼。

解決方案
在這個(gè)資源庫(kù)穩(wěn)定之前温赔,其實(shí)也是有其他解決方案的,一個(gè)是使用第三方資源庫(kù)鬼癣,另一個(gè)是使用 expect/actual 進(jìn)行平臺(tái)化實(shí)現(xiàn)(有點(diǎn)麻煩陶贼,且不合理)。

iOS 平臺(tái) JSON 序列化失敗

JSON 字符串轉(zhuǎn) ViewModel待秃,一個(gè)很常見(jiàn)的需求拜秧,在 KMM 中如何使用呢?可以使用 kotlinx-serialization-json 章郁,它是一個(gè)支持跨平臺(tái)的序列化庫(kù)

plugins {
    // 添加插件
    kotlin("plugin.serialization").version("1.9.20")
}

sourceSets {
    val commonMain by getting {
        dependencies {
            // Kotlin Json 解析
            implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.1")
        }
    }
}

用法可以參考:kotlinx-serialization-json - GitHub

下方這段代碼在 Android 平臺(tái)上是可以正常使用的枉氮,但是在 iOS 平臺(tái)上閃退了,目前還沒(méi)有定位到原因暖庄。

val list = json.decodeFromString<List<AboutGroupItemBean>>(response)


參考

Compose 和 Kotlin 版本的關(guān)聯(lián)關(guān)系

如何在 iOS 平臺(tái)上使用 Compose

Xcode 配置 KMM framework 打包腳本

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末聊替,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子培廓,更是在濱河造成了極大的恐慌惹悄,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肩钠,死亡現(xiàn)場(chǎng)離奇詭異泣港,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)价匠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)爷速,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人霞怀,你說(shuō)我怎么就攤上這事±蚋” “怎么了毙石?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)颓遏。 經(jīng)常有香客問(wèn)我徐矩,道長(zhǎng),這世上最難降的妖魔是什么叁幢? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任滤灯,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘鳞骤。我一直安慰自己窒百,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布豫尽。 她就那樣靜靜地躺著篙梢,像睡著了一般。 火紅的嫁衣襯著肌膚如雪美旧。 梳的紋絲不亂的頭發(fā)上渤滞,一...
    開(kāi)封第一講書(shū)人閱讀 51,198評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音榴嗅,去河邊找鬼妄呕。 笑死,一個(gè)胖子當(dāng)著我的面吹牛嗽测,可吹牛的內(nèi)容都是我干的绪励。 我是一名探鬼主播,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼论咏,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼优炬!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起厅贪,我...
    開(kāi)封第一講書(shū)人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蠢护,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后养涮,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體葵硕,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年贯吓,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了懈凹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡悄谐,死狀恐怖介评,靈堂內(nèi)的尸體忽然破棺而出托猩,到底是詐尸還是另有隱情蚪燕,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布粥血,位于F島的核電站情屹,受9級(jí)特大地震影響坪仇,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜垃你,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一椅文、第九天 我趴在偏房一處隱蔽的房頂上張望喂很。 院中可真熱鬧,春花似錦皆刺、人聲如沸少辣。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)毒坛。三九已至,卻和暖如春林说,著一層夾襖步出監(jiān)牢的瞬間煎殷,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工腿箩, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留豪直,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓珠移,卻偏偏與公主長(zhǎng)得像弓乙,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子钧惧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容