Jetpack Compose เป็นชุดเครื่องมือแบบประกาศที่ทันสมัยสำหรับสร้างอินเทอร์เฟส Android ใน Kotlin นักพัฒนาอธิบาย UI ผ่านฟังก์ชัน composable และชุดเครื่องมือจะวาดใหม่เฉพาะส่วนที่เปลี่ยนแปลงโดยอัตโนมัติ ตามข้อมูลจาก Android Developers (2026) Jetpack Compose ทำงานบน Android 5.0 (API 21) ขึ้นไป รองรับ Material Design 3 และบรรลุ 120 FPS บนอุปกรณ์ระดับกลางด้วยระบบ Recomposition ของตัวเอง — อัลกอริทึม diff อัจฉริยะที่อัปเดตเฉพาะวิดเจ็ตที่เปลี่ยนแปลง
ประเด็นสำคัญ
Jetpack Compose เป็นเฟรมเวิร์กแบบประกาศจาก Google สำหรับสร้างอินเทอร์เฟสผู้ใช้ Android ประกาศในปี 2019 และถึงเวอร์ชันเสถียรในปี 2021 แตกต่างจาก View System เดิม (เค้าโครง XML + Activity/Fragment) Compose ใช้ฟังก์ชัน Kotlin ที่มีคำอธิบายประกอบ — @Composable อินเทอร์เฟสอธิบายทั้งหมดใน Kotlin: ไม่มีการแบ่งแยกระหว่าง XML และโค้ด สิ่งนี้กำจัดข้อผิดพลาดที่เกี่ยวข้องกับ ID ที่ไม่ตรงกันใน XML และ Kotlin (type-safe synthetic ไม่ช่วยในการปรับโครงสร้าง)
Compose สร้างขึ้นบนระบบเรนเดอร์ของตัวเอง — Canvas ซึ่งไม่ผูกติดกับลำดับชั้น View Composable แต่ละตัววาดตัวเองบน Canvas โดยตรง ข้าม onMeasure/onDraw ของ View System สิ่งนี้ให้ประสิทธิภาพที่เพิ่มขึ้นบนหน้าจอที่ซับซ้อน: ในการทดสอบของ Google (2023) หน้าจอ Compose ที่มี 200 องค์ประกอบเรนเดอร์เร็วกว่าหน้าจอที่คล้ายกันบน RecyclerView + ViewHolder ถึง 40%
Compose ต้องการ minSdk 21 (Android 5.0) และ Kotlin 1.9+ Compose BOM (Bill of Materials) ซิงโครไนซ์เวอร์ชันของไลบรารี Compose ทั้งหมด เฟรมเวิร์กเข้ากันได้กับโค้ด View System ที่มีอยู่: Compose ถูกฝังผ่าน ComposeView ในเค้าโครง XML และ View เก่าผ่าน AndroidView ในลำดับชั้น Compose ตาม Google Play Console (2025) Android 5.0+ ครอบคลุม 97% ของอุปกรณ์ที่ใช้งานอยู่ ดังนั้นความเข้ากันได้จึงไม่ใช่ข้อจำกัดสำหรับโครงการส่วนใหญ่
@Composable คือคำอธิบายประกอบที่เปลี่ยนฟังก์ชัน Kotlin ทั่วไปให้เป็นบล็อกสร้าง UI ฟังก์ชัน Composable อธิบายว่าชิ้นส่วนของอินเทอร์เฟสควรมีลักษณะอย่างไร — ข้อความ ปุ่ม รายการ แทนที่จะคืนค่า ฟังก์ชันจะปล่อยส่วนประกอบ UI เข้าสู่องค์ประกอบ (emit) ซึ่งคล้ายกับตัวสร้าง: แต่ละฟังก์ชันเพิ่มองค์ประกอบบนหน้าจอเมื่อถูกเรียก
@Composable
fun ProfileCard(name: String, avatarUrl: String) {
Card(
modifier = Modifier.fillMaxWidth().padding(16.dp),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.surface
)
) {
Row(verticalAlignment = Alignment.CenterVertically) {
AsyncImage(
model = avatarUrl,
contentDescription = "อวาตาร์",
modifier = Modifier.size(48.dp).clip(CircleShape)
)
Spacer(Modifier.width(12.dp))
Text(
text = name,
style = MaterialTheme.typography.titleMedium
)
}
}
}
ฟังก์ชัน ProfileCard รับพารามิเตอร์ (name, avatarUrl) และปล่อย Card → Row → AsyncImage + Text องค์ประกอบ คือลำดับชั้นของส่วนประกอบที่ปล่อยออกมาในครั้งเดียว หากพารามิเตอร์ไม่เปลี่ยนแปลง Compose จะข้ามการเรียกฟังก์ชัน (recomposition skip) หากเฉพาะ name เปลี่ยนแปลง เฉพาะ Text จะถูกเรียก ส่วนที่เหลือจะไม่ถูกวาดใหม่ การจัดองค์ประกอบใหม่อย่างชาญฉลาดนี้เป็นข้อได้เปรียบด้านประสิทธิภาพหลักของ Compose เหนือการเพิ่มประสิทธิภาพด้วยตนเองของ View System
ฟังก์ชัน Composable ใช้สล็อตอย่างจริงจัง — trailing lambda, content: @Composable (() -> Unit) สิ่งนี้ช่วยให้สร้างคอนเทนเนอร์ได้: Card, Column, Row ยอมรับ lambda content และเนื้อหาจะถูกฝังในสล็อต Slot API แทนที่แอตทริบิวต์ XML เช่น android:layout_gravity — ตอนนี้ตำแหน่งขององค์ประกอบลูกถูกกำหนดโดยโค้ด Kotlin ภายในบล็อกเนื้อหา
สถานะ (State) ใน Compose คือค่าใดๆ ที่สามารถเปลี่ยนแปลงได้เมื่อเวลาผ่านไป เมื่อสถานะเปลี่ยนแปลง Compose จะกำหนดเวลาการจัดองค์ประกอบใหม่สำหรับส่วนประกอบทั้งหมดที่อ่านสถานะนี้ กลไกคล้ายกับ React hooks: mutableStateOf คืนค่า MutableState<T> การอ่าน .value จะสมัครสมาชิกองค์ประกอบปัจจุบันกับการเปลี่ยนแปลงโดยอัตโนมัติ
@Composable
fun CounterExample() {
var count by remember { mutableStateOf(0) }
Column(modifier = Modifier.padding(16.dp)) {
Text("คลิกแล้ว: $count")
Button(onClick = { count++ }) {
Text("เพิ่ม")
}
}
}
@Composable
fun UserScreen(viewModel: UserViewModel) {
val userName by viewModel.userName.collectAsState()
Text("ผู้ใช้: $userName")
}
remember รักษาค่าระหว่างการจัดองค์ประกอบใหม่ — มิฉะนั้น mutableStateOf จะถูกสร้างใหม่ทุกครั้งที่อัปเดต UI collectAsState() แปลง StateFlow จาก ViewModel เป็นสถานะที่เข้ากันได้กับ Compose คำแนะนำ — ใช้ ViewModel กับ StateFlow สำหรับสถานะระดับหน้าจอ และ mutableStateOf สำหรับสถานะภายใน (เช่น การ์ดที่ขยาย) การแบ่งนี้เป็นไปตามหลักการส่วนประกอบอัจฉริยะ/ธรรมดา
State Hoisting เป็นรูปแบบการยกสถานะจากส่วนประกอบลูกไปยังส่วนประกอบแม่ แม่ส่งค่าและ callback ผ่านพารามิเตอร์ ลูกเรียก callback เมื่อมีการเปลี่ยนแปลง แม่เก็บ mutableStateOf ลูกเก็บเฉพาะพารามิเตอร์ สิ่งนี้ทำให้ส่วนประกอบนำกลับมาใช้ใหม่ได้และทดสอบได้: TextField เดียวกันสามารถใช้กับแหล่งข้อมูลใดก็ได้
Modifier คือออบเจ็กต์ที่อธิบายการแปลงของ Composable: ขนาด ระยะห่าง พื้นหลัง การจัดการคลิก แอนิเมชัน การเลื่อน ตัวปรับแต่งถูกนำไปใช้ผ่านสายโซ่การเรียก: Modifier.fillMaxWidth().padding(16.dp).background(Color.Blue).clickable { } แต่ละการเรียกคืน Modifier ใหม่พร้อมคุณสมบัติที่เพิ่ม — ไม่มีการกลายพันธุ์ของออบเจ็กต์ดั้งเดิม
ลำดับของตัวปรับแต่งสำคัญ Modifier.padding(16.dp).background(Color.Blue) จะเติมสีพื้นที่ที่มีระยะห่าง Modifier.background(Color.Blue).padding(16.dp) จะเติมสีสี่เหลี่ยมด้านใน และระยะห่างยังคงโปร่งใส กลไก คล้ายกับโมเดลกล่อง CSS: padding ก่อน → background ทำงานเหมือน margin + background; background ก่อน → padding ทำงานเหมือน background + ระยะห่างภายใน นักพัฒนาเพียงจำไว้ว่า: padding ก่อน = ระยะขอบภายนอก padding หลัง = ระยะห่างภายใน
หากตัวปรับแต่งในตัวไม่เพียงพอ สามารถสร้างตัวปรับแต่งแบบกำหนดเองผ่าน Modifier.composed { ... } หรือ Modifier.then() ภายในตัวปรับแต่งแบบกำหนดเอง สามารถใช้การวัดเค้าโครง (Modifier.layout { measurable, constraints -> ... }) การวาด (Modifier.drawWithContent { ... }) ท่าทาง (Modifier.pointerInput { ... }) ตัวอย่าง: ตัวปรับแต่งสำหรับแอนิเมชันเร้าเมื่อคลิก — วัดขนาด เมื่อคลิกเริ่มแอนิเมชันมาตราส่วนผ่าน animateFloatAsState
สำหรับแอนิเมชัน Compose มี animate*AsState (animateFloatAsState, animateColorAsState, animateDpAsState) — ค่าจะเคลื่อนไหวระหว่างสถานะเก่าและใหม่เมื่อเปลี่ยนแปลง สำหรับแอนิเมชันเข้า/ออก — AnimatedVisibility และ AnimatedContent พร้อมการเปลี่ยนในตัว (fade, slide, expand) แอนิเมชันทั้งหมดทำงานบนเลเยอร์กราฟิกโดยไม่ก่อให้เกิดองค์ประกอบที่ไม่จำเป็น
ฟังก์ชัน Composable ไม่ควรดำเนินการข้างเคียงโดยตรง (คำขอเครือข่าย ตัวจับเวลา การสมัครรับข้อมูล) — ฟังก์ชันเหล่านี้ถูกเรียกในทุกการจัดองค์ประกอบใหม่ ซึ่งจะนำไปสู่คำขอที่ซ้ำกัน สำหรับเอฟเฟกต์ข้างเคียง Compose มีตระกูลฟังก์ชัน Effect: LaunchedEffect เริ่ม coroutine เมื่อเข้าสู่องค์ประกอบและยกเลิกเมื่อออก DisposableEffect — สำหรับทรัพยากรที่ต้องการการล้างข้อมูลอย่างชัดเจน (เซ็นเซอร์, BroadcastReceiver)
@Composable
fun SensorReader() {
val context = LocalContext.current
var sensorValue by remember { mutableStateOf(0f) }
DisposableEffect(Unit) {
val sensor = registerSensorListener(context) { value ->
sensorValue = value
}
onDispose {
unregisterSensorListener(sensor)
}
}
Text("ค่า: $sensorValue")
}
@Composable
fun UserGreeting(userId: String) {
LaunchedEffect(userId) {
val profile = api.fetchProfile(userId)
// อัปเดตสถานะ
}
}
LaunchedEffect(userId) เริ่มใหม่หาก userId เปลี่ยนแปลง — coroutine ก่อนหน้าถูกยกเลิก และอันใหม่เริ่มด้วย userId ใหม่ สิ่งนี้ช่วยลดการจัดการการยกเลิกคำขอด้วยตนเอง DisposableEffect(Unit) — เอฟเฟกต์ที่มีคีย์คงที่ Unit ทำงานเมื่อเข้าสู่องค์ประกอบและเรียก onDispose เมื่อออก SensorReader ลงทะเบียนผู้ฟังและยกเลิกการสมัครเมื่อออกจากหน้าจอ — โดยไม่มีความเสี่ยงในการรั่วไหล
หากจำเป็นต้องเริ่ม coroutine ไม่ใช่เมื่อเข้าสู่องค์ประกอบ แต่เมื่อเกิดเหตุการณ์ (คลิกปุ่ม) ให้ใช้ rememberCoroutineScope() มันคืน CoroutineScope ที่ผูกกับวงจรชีวิตของ Composable โดยไม่ต้องใช้ DisposableEffect ตัวอย่าง: เริ่มคำขอเครือข่ายเมื่อคลิกปุ่ม — scope.launch { viewModel.loadData() }
การเลือกระหว่าง Compose และ View System เป็นคำถามทางสถาปัตยกรรมหลักสำหรับนักพัฒนา Android ในปี 2026 ทั้งสองเทคโนโลยีรองรับโดย Google แต่ Compose เป็นทิศทางหลักที่ Google ใช้ทรัพยากร View System ได้รับเฉพาะการแก้ไขที่สำคัญและไม่พัฒนา ความแตกต่างปรากฏในไวยากรณ์ การจัดการสถานะ ประสิทธิภาพ และเวลาในการพัฒนา
| ด้าน | Jetpack Compose | View System |
|---|---|---|
| คำอธิบาย UI | ฟังก์ชัน Kotlin @Composable | เค้าโครง XML + Activity/Fragment |
| สถานะ | mutableStateOf, StateFlow, การวาดใหม่อัตโนมัติ | findViewById, ด้วยตนเอง: setText, notifyDataSetChanged |
| ประสิทธิภาพ | การจัดองค์ประกอบใหม่อัจฉริยะ, การเรนเดอร์ Canvas | ลำดับชั้น View, measure/layout/draw |
| แอนิเมชัน | animate*AsState, AnimatedVisibility, ในตัว | ValueAnimator, ObjectAnimator, Transition |
| ความเข้ากันได้ | minSdk 21, สะพาน ComposeView/AndroidView | ทุกเวอร์ชัน, ทุก |
| ขนาด APK | +3–5 MB สำหรับ Compose | ไม่มีค่าใช้จ่ายเพิ่มเติม |
สำหรับโครงการใหม่ Google แนะนำ Jetpack Compose เป็นมาตรฐานการพัฒนา UI View System ยังคงอยู่สำหรับการบำรุงรักษาโค้ดที่เขียนก่อนปี 2021 และกรณีที่ขนาด APK ขั้นต่ำสำคัญ (เช่น สำหรับตลาดเกิดใหม่ที่มีอุปกรณ์ระดับเริ่มต้น) Compose ลดปริมาณโค้ด UI ลง 30–50% เมื่อเทียบกับ View System เนื่องจากไวยากรณ์แบบประกาศและแอนิเมชันในตัว
คำถามที่พบบ่อย
ได้ ผ่าน ComposeView ในเค้าโครง XML เพิ่ม dependency Compose และห่อหน้าจอหรือบางส่วนใน ComposeView { MyComposable() } การย้ายทำทีละหน้าจอ
สาเหตุคือสถานะถูกยกสูงเกินไปหรือใช้ออบเจ็กต์ที่เปลี่ยนแปลงได้ การแก้ไข: derivedStateOf สำหรับข้อมูลที่ได้มาและ remember สำหรับการอ้างอิงที่เสถียร
ใช้ LazyColumn (คล้ายกับ RecyclerView) องค์ประกอบถูกสร้างและนำกลับมาใช้ใหม่เมื่อเลื่อน สำหรับรายการที่ซับซ้อนที่มีประเภทเซลล์ต่างกัน — LazyColumn { items(items, key = { it.id }) { ... } }
ไม่ คุณสามารถเริ่มด้วย Compose ได้ทันที ความรู้ View System ช่วยในการบำรุงรักษาโค้ดเก่า แต่ Compose เป็นระบบนิเวศอิสระที่มีเอกสารและรูปแบบของตัวเอง
ใช่ Material 3 เป็นธีมมาตรฐานของ Compose ตั้งแต่ปี 2023 เพิ่มผ่าน implementation("androidx.compose.material3:material3") Material 2 ถือว่าล้าสมัย
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ