KMM+Compose 开发一个Kotlin多平台应用

前言

现在跨平台开发框架有很多,比如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中都可以调用:

 KMM多平台能力

我们看一下App.kt中的getPlatformName()函数,可以发现他是这样声明的:

 这个相当于在共享模块声明它的签名,然后我们可以在每个平台中进行实现

androidMain目录中该函数的实现(desktopMain中实现也是这样):

这样我们就拥有了多平台开发能力,只要将平台间不兼容的地方声明一个待实现的多平台函数,然后在每个平台实现,就可以在commonMain中轻松使用了

 接下来我们就去写一个简单的程序

正文

compose写ui

我们要实现的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的滚动是滚动鼠标滚轮)

使用KMM多平台方法

首先我们在commonMain的platform.kt文件中定义一下expect fun:

然后我们在androidMain和desktopMain中实现一下这个函数,为了简单就直接写死一个数了, 

然后我们稍微改一下ui:

在 Text("总数量:$number") 下面增加如下代码:

ps:调用多平台函数可能没有代码提示emmm

            Button({
                number = getNumber()
            }) {
                Text("从本地加载数量")
            }

 然后一个简单的多平台应用就搞好了,后面有时间再写更复杂的功能

源码: ltttttttttttt/KMM_and_Compose_Sample

end

猜你喜欢

转载自blog.csdn.net/qq_33505109/article/details/123497999