Skip to Content
KMP📚 Học KMPGiới thiệu CMP

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ì?

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

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