KMP+Compose UseCase01——屏幕适配

106 阅读2分钟

引言

(以下引言文案由ChatGpt生成)

随着移动应用的多平台化趋势,跨端开发成为了一个备受关注的话题。在Android开发中,Kotlin Multiplatform (KMP) 和 Jetpack Compose 技术的崛起为开发者们提供了更加灵活和高效的跨端开发方案。屏幕适配的挑战在跨端开发中变得更加复杂,因为开发者不仅需要考虑不同的Android设备,还需要处理不同平台(如iOS)上的适配问题。

KMP 允许开发者使用Kotlin编写可在多个平台上共享的代码,包括Android和iOS。这使得在不同平台上实现一致的屏幕适配变得更加容易,同时为开发者提供了更高的代码重用性。结合Jetpack Compose,开发者可以使用声明式的UI编写方式,更加方便地构建适配多屏幕的用户界面。

本文将深入探讨在KMP和Jetpack Compose环境下的屏幕适配策略,介绍如何利用这些新技术解决跨平台和多屏幕尺寸带来的挑战。我们将探讨一些实际案例和最佳实践,帮助开发者更好地理解如何利用跨端开发技术构建灵活、高效、同时又在各类设备上呈现一致性的用户界面。

在这个移动开发的新时代,结合KMP和Jetpack Compose的屏幕适配不仅是技术上的创新,更是为开发者提供了更广阔的跨平台开发视野。通过深入了解和灵活应用这些技术,开发者可以更好地应对跨平台和多屏幕带来的挑战,为用户提供更加流畅、一致的移动应用体验。

commonMain

// Screen.kt
/**
 * 定义方法用于提供基于设计图的屏幕缩放系数
 */
expect fun getScreenScale(designWidth: Float): Float

androidMain

// Screen.kt
actual fun getScreenScale(designWidth: Float): Float {
    val matrics = Resources.getSystem().displayMetrics
    return matrics.widthPixels / matrics.density / designWidth
}
}

iosMain

// ScreenAdapter.kt
import kotlinx.cinterop.ExperimentalForeignApi
import kotlinx.cinterop.useContents
import platform.UIKit.UIScreen

@OptIn(ExperimentalForeignApi::class)
actual fun getScreenScale(designWidth: Float): Float {
    val mainScreen = UIScreen.mainScreen
    val screenWidth = mainScreen.bounds().useContents {
        this.size.width
    }
    return screenWidth.toFloat() / designWidth
}

Compose dp替换为sdp

import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import getScreenScale

/**
 * 定义设计图宽
 */
private const val designWidth = 375f

/**
 * 默认使用宽度适配,根据需求切换
 * 定义根据宽适配的缩放比例
 * 1、屏幕宽度和设计图宽比例,获得density的缩放值
 * 2、根据这个值去获取对应dp
 */
private val scale: Float
    get() {
        return getScreenScale(designWidth = designWidth)
    }

val Int.sdp get() = (this * scale).dp

val Double.sdp get() = (this * scale).toInt().dp

val Int.ssp get() = (this * scale).sp

val Double.ssp get() = (this * scale).toInt().sp

使用案例

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.widget.theme.sdp

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Widget(onBackPress: () -> Unit) {
    Box(
        Modifier.statusBarsPadding()
            .size((375/2).sdp)
            .background(MaterialTheme.colorScheme.primary)
    )
}

图例IOS

22421701609233_.pic.jpg

图例Android

image.png