Skip to Content

Giới thiệu Compose Multiplatform

Compose Multiplatform cho phép bạn chia sẻ cả UI lẫn logic giữa các nền tảng bằng Jetpack Compose.

Compose Multiplatform là gì?

┌─────────────────────────────────────────┐ │ Compose Multiplatform UI │ │ (Button, Text, Column, Row, ...) │ ├─────────────────────────────────────────┤ │ Kotlin Multiplatform (KMP) │ │ (Business logic, networking, DB) │ ├───────────┬───────────┬─────────────────┤ │ Android │ iOS │ Desktop/Web │ └───────────┴───────────┴─────────────────┘

Deployment targets

PlatformTechnologyStatus
AndroidJetpack Compose✅ Stable
iOSSkiko/UIKit✅ Stable
DesktopSkiko/JVM✅ Stable
Web (Wasm)Wasm/Canvas🧪 Alpha

So sánh với Flutter và React Native

Compose MultiplatformFlutterReact Native
LanguageKotlinDartJavaScript
UI EngineSkia + NativeSkiaNative bridge
Learning curveDễ nếu biết ComposeMớiDễ nếu biết React
Native integrationExcellentGoodModerate
PerformanceNear-nativeExcellentGood
EcosystemGrowingLargeVery large

Composable hoạt động như thế nào trên iOS?

1. Compile flow

Kotlin Code Kotlin/Native Compiler iOS Framework (.framework) Swift/Obj-C Integration iOS App

2. Rendering

Compose Multiplatform sử dụng Skia để render UI giống nhau trên mọi platform:

  • Skia là graphics library của Google (cũng dùng trong Chrome, Android)
  • UI được vẽ pixel-by-pixel, đảm bảo consistency

3. Tích hợp với UIKit

// iOS App có thể wrap Compose UI trong UIViewController import ComposeApp struct ContentView: View { var body: some View { ComposeView() } }

Bắt đầu với Compose Multiplatform

Tạo project từ Wizard

  1. Truy cập https://kmp.jetbrains.com/ 
  2. Chọn Compose Multiplatform Application
  3. Chọn platforms: Android, iOS, Desktop (optional)
  4. Download và mở trong Android Studio

Cấu trúc UI module

composeApp/src/ ├── commonMain/kotlin/ │ ├── App.kt # Root composable │ ├── theme/ │ │ ├── Theme.kt │ │ └── Color.kt │ ├── ui/ │ │ ├── screen/ │ │ │ ├── HomeScreen.kt │ │ │ └── DetailScreen.kt │ │ └── component/ │ │ ├── Button.kt │ │ └── Card.kt │ └── navigation/ │ └── Navigation.kt ├── androidMain/kotlin/ │ └── MainActivity.kt └── iosMain/kotlin/ └── MainViewController.kt

Compose Multiplatform vs Jetpack Compose

Hầu hết code Jetpack Compose hoạt động ngay trong Compose Multiplatform:

✅ Hoạt động như nhau

// Các composables cơ bản Text("Hello") Button(onClick = {}) { Text("Click") } Column { ... } Row { ... } Box { ... } LazyColumn { ... } // State management var count by remember { mutableStateOf(0) } val state by viewModel.state.collectAsState() // Material 3 MaterialTheme { ... } Card { ... } Scaffold { ... }

⚠️ Cần thay đổi nhỏ

// Jetpack Compose (Android only) import androidx.compose.ui.res.painterResource // Compose Multiplatform import org.jetbrains.compose.resources.painterResource import myapp.composeapp.generated.resources.Res import myapp.composeapp.generated.resources.my_image Image( painter = painterResource(Res.drawable.my_image), contentDescription = null )

❌ Không có sẵn (cần expect/actual)

  • Camera
  • Sensors
  • Platform-specific APIs
  • Some Material 3 components (adaptive)

Ví dụ: App đơn giản

// commonMain/App.kt import androidx.compose.foundation.layout.* import androidx.compose.material3.* import androidx.compose.runtime.* @Composable fun App() { MaterialTheme { var count by remember { mutableStateOf(0) } Surface(modifier = Modifier.fillMaxSize()) { Column( modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { Text( text = "Count: $count", style = MaterialTheme.typography.headlineLarge ) Spacer(Modifier.height(16.dp)) Button(onClick = { count++ }) { Text("Increment") } } } } }

Code này chạy identical trên Android, iOS, và Desktop!


Platform-specific entry points

Android - MainActivity.kt

class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { App() } } }

iOS - MainViewController.kt

fun MainViewController() = ComposeUIViewController { App() }

Desktop - main.kt

fun main() = application { Window( onCloseRequest = ::exitApplication, title = "My App" ) { App() } }

Resources trong Compose Multiplatform

Setup

// build.gradle.kts compose.resources { publicResClass = true packageOfResClass = "com.example.myapp.resources" generateResClass = always }

Thêm resources

composeApp/src/commonMain/composeResources/ ├── drawable/ │ └── logo.png ├── font/ │ └── roboto.ttf └── values/ └── strings.xml

Sử dụng

import myapp.composeapp.generated.resources.Res import myapp.composeapp.generated.resources.logo import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.stringResource @Composable fun LogoImage() { Image( painter = painterResource(Res.drawable.logo), contentDescription = "Logo" ) }

📝 Tóm tắt

Khái niệmMô tả
Compose MultiplatformUI framework chung cho các platforms
commonMainCode UI chạy trên tất cả platforms
ComposeUIViewControllerEntry point cho iOS
ResType-safe resources
SkiaRendering engine

Khi nào dùng Compose Multiplatform?

Phù hợp:

  • App cần UI giống nhau trên Android/iOS
  • Team đã biết Jetpack Compose
  • App không cần native UI phức tạp

⚠️ Cân nhắc:

  • Cần native UI đặc thù (Maps, Camera UI, …)
  • Team chưa biết Kotlin/Compose

Tiếp theo

Học cách Xây dựng UI chung với Compose Multiplatform.

Last updated on