Jetpack Compose คือเฟรมเวิร์ก UI แบบประกาศที่ทันสมัยจาก Google สำหรับการพัฒนา Android ซึ่งเปิดตัวในเวอร์ชันเสถียร 1.0 ในเดือนกรกฎาคม 2021 Compose แทนที่เค้าโครง XML เชิงคำสั่งและระบบ View ด้วยฟังก์ชัน Kotlin ที่มีคำอธิบายประกอบ @Composable ตามข้อมูลจาก Google I/O (2025) Compose ถูกใช้ใน 55% ของโปรเจกต์ Android ใหม่ และขนาดโค้ด UI โดยเฉลี่ยลดลง 30–50% เมื่อเทียบกับ XML เฟรมเวิร์กจะวาดใหม่เฉพาะส่วนที่เปลี่ยนแปลงของหน้าจอโดยอัตโนมัติเมื่อ State เปลี่ยนแปลง ไม่จำเป็นต้องเรียก notifyDataSetChanged หรือ findViewById ด้วยตนเอง
ประเด็นสำคัญ
Jetpack Compose คือเฟรมเวิร์ก UI ของ Google ที่สร้างบนหลักการเขียนโปรแกรมเชิงตอบสนอง แทนที่จะใช้ Activity กับเค้าโครง XML, FragmentManager และ ViewBinding นักพัฒนาอธิบายอินเทอร์เฟซผ่านฟังก์ชัน Kotlin ที่มีคำอธิบายประกอบ @Composable Compose ไม่ใช้ LayoutInflater — UI คือฟังก์ชัน Kotlin บริสุทธิ์ที่ถูกคอมไพล์เป็นไบต์โค้ด เฟรมเวิร์กประกอบด้วยหลายไลบรารี: Compose UI (ส่วนประกอบพื้นฐาน Text, Button, Column, Row), Compose Foundation (Material Design, Gestures, Focus), Compose Material3 (Material You พร้อม Dynamic Colors) และ Compose Runtime (State, Side Effects, Coroutines) Compose ทำงานบน Android API 21+ (Android 5.0) และเข้ากันได้อย่างสมบูรณ์กับโค้ด View/XML ที่มีอยู่ผ่าน ComposeView — ตัวปรับต่อ AndroidView
View System (2008) ใช้ลำดับชั้นของออบเจ็กต์ View ที่มีการจัดการด้วยตนเอง: นักพัฒนาสร้างเค้าโครง XML, ค้นหา Views ผ่าน findViewById, ใช้ Adapter สำหรับ RecyclerView และเรียก notifyDataSetChanged เมื่อข้อมูลเปลี่ยนแปลง Compose อธิบาย UI เชิงฟังก์ชัน: เมื่อสถานะเปลี่ยน เฟรมเวิร์กจะประกอบใหม่เฉพาะฟังก์ชัน Composable ที่เปลี่ยน คำนวณ diff และใช้การเปลี่ยนแปลงน้อยที่สุดกับ Canvas ประสิทธิภาพของ Compose เทียบได้กับ View System และในสถานการณ์ที่มีรายการซับซ้อน (LazyColumn) มักจะเหนือกว่า RecyclerView เนื่องจากการข้ามองค์ประกอบที่ไม่จำเป็นผ่านพารามิเตอร์ key ที่ IT Sectr ใช้ Compose สำหรับโมดูลใหม่ของแอปพลิเคชัน Android ที่มี minSdk 24+
@Composable — คำอธิบายประกอบที่เปลี่ยนฟังก์ชัน Kotlin ทั่วไปให้เป็นส่วนประกอบสำคัญของ UI ฟังก์ชัน Composable สามารถเรียกฟังก์ชัน Composable อื่นๆ เพื่อสร้างเป็นแผนผังส่วนประกอบ แตกต่างจาก View ตรงที่ฟังก์ชัน Composable ไม่มีสถานะโดยค่าเริ่มต้น — พวกมันไม่มีสถานะ (stateless) และถูกวาดใหม่ทุกครั้งที่พารามิเตอร์อินพุตหรือ State เปลี่ยนแปลง Compose Compiler เปลี่ยนฟังก์ชัน @Composable เป็นโค้ดที่สามารถถูกขัดจังหวะและดำเนินการต่อได้ (positional memoization) — ซึ่งช่วยให้ Compose เริ่มต้นใหม่เฉพาะส่วนที่เปลี่ยนแปลงโดยไม่ต้องสร้างแผนผังใหม่ทั้งหมด
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@Composable
fun UserProfile(name: String, avatarUrl: String) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
verticalAlignment = Alignment.CenterVertically
) {
AsyncImage(
model = avatarUrl,
contentDescription = "User avatar",
modifier = Modifier.size(48.dp)
)
Spacer(modifier = Modifier.width(12.dp))
Text(
text = name,
style = MaterialTheme.typography.titleMedium
)
}
}ฟังก์ชัน UserProfile รับ name และ avatarUrl เป็นพารามิเตอร์ สร้างแถวที่มีรูปประจำตัวและชื่อ Modifier.fillMaxWidth() ขยายส่วนประกอบให้เต็มความกว้าง .padding(16.dp) เพิ่มระยะห่าง MaterialTheme.typography.titleMedium ใช้สไตล์ระบบ Material 3 เมื่อพารามิเตอร์ name หรือ avatarUrl เปลี่ยนแปลง Compose จะประกอบ UserProfile ใหม่ — สร้างส่วนประกอบใหม่ด้วยค่าใหม่
State ใน Compose คือค่าใดๆ ที่การเปลี่ยนแปลงทำให้เกิดการประกอบใหม่ (เริ่มต้นใหม่) ของฟังก์ชัน @Composable ที่ขึ้นต่อกัน วิธีพื้นฐานคือ mutableStateOf() ซึ่งสร้าง MutableState<T> ที่รองรับระบบสแนปชอตของ Compose สแนปชอตเป็นกลไกติดตามการเปลี่ยนแปลง: เมื่อเขียน State Compose จะทำเครื่องหมายสแนปชอตปัจจุบันว่าสกปรก (dirty) และตัวจัดตารางการประกอบใหม่จะเริ่มต้นเฉพาะฟังก์ชัน Composable ที่อ่าน State นั้น สำหรับคอลเล็กชันที่สังเกตได้ ให้ใช้ mutableStateListOf() และ mutableStateMapOf() Compose รองรับ State จากส่วนประกอบ Lifecycle-Aware ผ่าน collectAsState() สำหรับ Kotlin Flow และ observeAsState() สำหรับ LiveData
@Composable
fun LikeButton() {
var liked by remember { mutableStateOf(false) }
var count by remember { mutableStateOf(42) }
Button(
onClick = {
liked = !liked
if (liked) count++ else count--
},
colors = ButtonDefaults.buttonColors(
containerColor = if (liked) MaterialTheme.colorScheme.primary
else MaterialTheme.colorScheme.surfaceVariant
)
) {
Text("♥ $count")
}
}โค้ดสร้างปุ่ม "Like" ที่มีสถานะ liked (Boolean) และ count (Int) เก็บผ่าน mutableStateOf() เมื่อกด liked จะกลับด้านและตัวนับเพิ่ม/ลด — Compose จะประกอบ LikeButton ใหม่โดยอัตโนมัติ ตัวแทน by อนุญาตให้ใช้ State เหมือนตัวแปรทั่วไป: liked = !liked แทน liked.value = !liked.value สีของปุ่มเปลี่ยนแบบตอบสนองระหว่าง primary (ถูกใจ) และ surfaceVariant (ไม่ถูกใจ)
remember — ฟังก์ชัน Compose ที่แคชค่าระหว่างการประกอบใหม่ หากไม่มี remember การเริ่มต้นใหม่แต่ละครั้งของฟังก์ชัน Composable จะสร้างสถานะใหม่ (mutableStateOf) — ซึ่งทำให้ตรรกะของแอปพลิเคชันเสียหาย: เมื่อหมุนหน้าจอหรือเปลี่ยน State หลัก ตัวนับจะถูกรีเซ็ต remember รับแลมบ์ดาคำนวณและคำนวณค่าเฉพาะในการประกอบครั้งแรกเท่านั้น ครั้งต่อมาจะคืนผลลัพธ์ที่แคชไว้ หากต้องการรีเซ็ตแคชให้ใช้ remember(key) — คีย์จะกำหนดว่าจะคำนวณค่าใหม่เมื่อใด remember(key1, key2) จะคำนวณใหม่เมื่อคีย์ใดคีย์หนึ่งเปลี่ยน สำหรับสถานะที่มีอายุยืนยาว (ทนต่อการหมุนหน้าจอ) ให้ใช้ rememberSaveable — คล้าย remember แต่บันทึกใน Bundle ผ่าน SavedStateHandle
@Composable
fun TimerScreen() {
var seconds by rememberSaveable { mutableStateOf(0) }
LaunchedEffect(Unit) {
while (true) {
delay(1000)
seconds++
}
}
Column(
modifier = Modifier.fillMaxSize().padding(32.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "Elapsed: ${seconds}s",
style = MaterialTheme.typography.displayMedium
)
}
}rememberSaveable รักษา seconds เมื่อหมุนหน้าจอ (การเปลี่ยนแปลงการกำหนดค่า) LaunchedEffect เริ่มคอรู่ทีนที่เพิ่ม seconds ทุกวินาที ในการประกอบใหม่ของ TimerScreen (ทุกวินาที) seconds จะไม่ถูกรีเซ็ตด้วย rememberSaveable ใช้ remember ปกติสำหรับสถานะที่ไม่ควรรอดจากการเปลี่ยนแปลงการกำหนดค่า (เช่น ธงแอนิเมชัน)
Modifier — ออบเจ็กต์คอนเทนเนอร์ที่ไม่เปลี่ยนรูปซึ่งใช้รูปแบบ Builder เพื่อกำหนดลักษณะ พฤติกรรม และเค้าโครงของส่วนประกอบ Composable ทุกครั้งที่เรียกเมธอด Modifier (.padding(), .width(), .clickable(), .background()) จะคืนค่า Modifier ใหม่ที่เพิ่มองค์ประกอบเข้าไป ลำดับของตัวปรับแต่งมีความสำคัญ: .padding(16.dp).clickable { } — ระยะห่างถูกใช้ก่อนตัวจัดการคลิก clickable ติดตามพื้นที่ทั้งหมดรวมถึงระยะห่าง .clickable { }.padding(16.dp) — พื้นที่ทั้งหมดก่อนระยะห่างสามารถคลิกได้ ระยะห่างเลื่อนเนื้อหาเข้าไปด้านใน Modifier รองรับการใช้งานแบบกำหนดเองผ่าน then(otherModifier) และ compositionLocal สำหรับเข้าถึงการตั้งค่าหลัก
@Composable
fun CardExample() {
Card(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.clickable { println("Card clicked") },
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.surfaceVariant
)
) {
Column(modifier = Modifier.padding(16.dp)) {
Text("Jetpack Compose", style = MaterialTheme.typography.titleLarge)
Spacer(modifier = Modifier.height(8.dp))
Text(
"UI แบบประกาศสำหรับ Android ด้วย State และ Modifier",
style = MaterialTheme.typography.bodyMedium
)
}
}
}CardExample แสดงห่วงโซ่ Modifier: fillMaxWidth + padding + clickable Card คือส่วนประกอบ Material3 ที่มีการตั้งค่า elevation และ colors ของตัวเอง Column ที่ซ้อนกันมีระยะห่างภายใน 16dp Compose Material3 จะปรับสีให้เข้ากับ Dynamic Color (Material You) โดยอัตโนมัติบน Android 12+ Card เป็นหนึ่งในส่วนประกอบ Material3 ในตัวกว่า 30 รายการใน Compose
State hoisting — รูปแบบการยกระดับสถานะออกจากฟังก์ชัน Composable ไปยังผู้เรียก ทำให้ฟังก์ชันไม่มีสถานะ (stateless) ส่วนประกอบที่ไม่มีสถานะจะรับข้อมูลและ callback ผ่านพารามิเตอร์โดยไม่ได้เป็นเจ้าของ State ด้วยตัวเอง ซึ่งช่วยเพิ่มความสามารถในการนำกลับมาใช้ใหม่และการทดสอบ: ส่วนประกอบสามารถถูกเรียกด้วย State ต่างๆ และทดสอบในตัวอย่างแสดงตัวอย่าง Google แนะนำสถาปัตยกรรม: ViewModel + StateFlow (หรือ MutableStateFlow) + collectAsState() ใน Compose ViewModel ยกระดับสถานะไปยังระดับหน้าจอ Compose แสดงผล เอฟเฟกต์ข้างเคียง (LaunchedEffect, DisposableEffect) จัดการเหตุการณ์ครั้งเดียว
| ส่วนประกอบ | ความรับผิดชอบ | เทคโนโลยี |
|---|---|---|
| ViewModel | การจัดเก็บ State, ตรรกะทางธุรกิจ | StateFlow, MutableStateFlow |
| Screen Composable | การจัดระเบียบหน้าจอ, State hoisting | collectAsState(), Scaffold, LazyColumn |
| Stateless Component | UI ไม่มีสถานะ, การแสดงผลบริสุทธิ์ | พารามิเตอร์ @Composable + แลมบ์ดา |
| Side Effect | การกระทำครั้งเดียว (snackbar, การนำทาง) | LaunchedEffect, SnackbarHostState |
คำถามที่พบบ่อย
เค้าโครง XML เป็นเชิงคำสั่ง: LayoutInflater โหลด XML, findViewById ค้นหา Views, นักพัฒนาอัปเดตข้อความ/รายการด้วยตนเอง Compose เป็นแบบประกาศ: UI อธิบายด้วยฟังก์ชัน Kotlin @Composable และเฟรมเวิร์กจะวาดใหม่เฉพาะส่วนที่เปลี่ยนแปลงโดยอัตโนมัติเมื่อ State เปลี่ยนแปลง Compose ลดปริมาณโค้ด UI ลง 30–50% และไม่ใช้ XML
ใช่ Google มี Navigation Compose — ไลบรารีสำหรับการนำทางแบบประกาศระหว่างหน้าจอ NavController จัดการสแต็กเส้นทาง composable() ลงทะเบียนหน้าจอ navArgument ส่งผ่านพารามิเตอร์ ทางเลือกอื่น: Voyager (community) และ Decompose (Badoo) Navigation Compose เป็นมาตรฐานทางการที่รองรับ deep links และอาร์กิวเมนต์ type-safe
Modifier คือคอนเทนเนอร์ที่ไม่เปลี่ยนรูปของรูปแบบการตกแต่ง (padding, size, clickable, background, border, clip) ที่ใช้กับส่วนประกอบ Composable ทุกครั้งที่เรียกจะคืนค่า Modifier ใหม่ที่เพิ่มองค์ประกอบเข้าไป ลำดับสำคัญ: .padding().clickable() ใช้ระยะห่างก่อนคลิก .clickable().padding() — ตรงกันข้าม Modifier เป็นวิธีหลักในการปรับแต่งส่วนประกอบ Compose
Jetpack Compose รองรับ Android API 21+ (Android 5.0 Lollipop) ผ่าน Compose Compiler และ Compose BOM Material 3 (Dynamic Colors) ใช้งานได้บน Android 12+ สำหรับเวอร์ชันเก่าจะใช้ชุดสีสำรอง สำหรับโปรเจกต์ใหม่ Google แนะนำ minSdk 24+ (Android 7.0) ซึ่ง Compose รองรับอย่างเต็มที่
Google มี Compose UI Test — ไลบรารีสำหรับทดสอบบน JVM (เดสก์ท็อป) และอีมูเลเตอร์ ฟังก์ชันหลัก: composeTestRule.setContent { } สำหรับแสดงส่วนประกอบ, onNodeWithText() สำหรับค้นหาองค์ประกอบ, performClick()/performTextInput() สำหรับการดำเนินการ การทดสอบ Espresso เข้ากันได้กับ Compose ผ่าน ComposeTestRule แต่ Compose UI Test เป็นวิธีที่เร็วกว่าและเป็นที่นิยม
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ