面试题答案
一键面试解决不同平台 UI 显示不一致问题
- 建立设计系统
- 定义一套统一的颜色、字体、间距等基础样式。例如,创建一个
Theme.kt
文件,在其中定义颜色调色板:
object AppColors { val primary = Color(0xFF123456) val secondary = Color(0xFF7890AB) }
- 对于字体,使用
Typography
来规范不同层级文本的样式,如标题、正文等。
val AppTypography = Typography( h1 = TextStyle(fontSize = 28.sp, fontWeight = FontWeight.Bold), body1 = TextStyle(fontSize = 16.sp) )
- 定义一套统一的颜色、字体、间距等基础样式。例如,创建一个
- 使用跨平台组件库
- 优先使用 Compose 提供的通用组件,如
Button
、Text
等。对于自定义组件,确保在不同平台上的外观和行为尽可能一致。例如,在创建自定义卡片组件时,通过统一的shape
、elevation
等属性来保证跨平台显示一致。
@Composable fun CustomCard(content: @Composable () -> Unit) { Card( shape = RoundedCornerShape(8.dp), elevation = 4.dp, backgroundColor = AppColors.secondary, content = content ) }
- 优先使用 Compose 提供的通用组件,如
- 平台特定适配
- 对于无法避免的平台差异,利用 Compose 的
@OptIn(ExperimentalMaterialApi::class)
注解以及平台特定的修饰符。例如,在 Android 上可能需要特殊处理状态栏颜色,在AndroidManifest.xml
中设置android:statusBarColor
,同时在 Compose 中使用WindowInsets
来调整布局与状态栏的关系。
CompositionLocalProvider( LocalWindowInsets provides WindowInsets(0, 0, 0, 0), content = { // 布局内容 } )
- 在 iOS 上,可以利用
UIKit
的一些特性来进行特定的适配,通过iOSView
等方式将原生视图嵌入 Compose 布局中。
- 对于无法避免的平台差异,利用 Compose 的
解决 Compose 与原生平台功能交互复杂问题
- 使用接口抽象
- 定义跨平台接口,例如创建一个
PlatformFeature.kt
文件,定义获取设备信息的接口:
interface PlatformInfoProvider { fun getDeviceModel(): String }
- 在不同平台实现该接口。在 Android 上,通过
Build.MODEL
来实现:
class AndroidPlatformInfoProvider : PlatformInfoProvider { override fun getDeviceModel(): String = Build.MODEL }
- 在 iOS 上,通过
UIDevice.current.name
来实现(使用 Kotlin/Native 与 Swift 交互的相关机制)。
- 定义跨平台接口,例如创建一个
- Kotlin/Native 互操作性
- 对于 iOS 和桌面端(如 macOS、Windows、Linux),利用 Kotlin/Native 的互操作性。例如,在 iOS 上与 Swift 交互,首先在 Kotlin 中定义
@ObjC
注解的函数或类:
@ObjC class NativeUtils { @ObjC fun callNativeFunction(): String { return "Called from Kotlin/Native" } }
- 在 Swift 中可以通过
import KotlinNative
来调用这些函数。
- 对于 iOS 和桌面端(如 macOS、Windows、Linux),利用 Kotlin/Native 的互操作性。例如,在 iOS 上与 Swift 交互,首先在 Kotlin 中定义
- Android 特定交互
- 在 Android 上,利用 Compose 的
AndroidView
来嵌入原生 Android 视图。例如,要嵌入一个RecyclerView
:
AndroidView( factory = { context -> RecyclerView(context).apply { // 设置布局管理器等 } }, update = { recyclerView -> // 更新 RecyclerView 的数据等操作 } )
- 同时,利用 Compose 的
ContextAmbient
来获取 Android 上下文,以便调用 Android 原生功能,如资源加载等。
val context = LocalContext.current val resourceId = context.resources.getIdentifier("image_name", "drawable", context.packageName)
- 在 Android 上,利用 Compose 的