Jetpack Compose: nền tảng, hàm Composable và State

Tác giả: IT Sectr Đã đăng: 2026-02-21 Thời gian đọc: 8 phút

Jetpack Compose là framework UI khai báo hiện đại của Google dành cho phát triển Android, được phát hành phiên bản ổn định 1.0 vào tháng 7 năm 2021. Compose thay thế bố cục XML mệnh lệnh và hệ thống View bằng các hàm Kotlin với chú thích @Composable. Theo Google I/O (2025), Compose được sử dụng trong 55% dự án Android mới và kích thước mã UI trung bình giảm 30–50% so với XML. Framework tự động vẽ lại chỉ những phần đã thay đổi của màn hình khi State thay đổi, loại bỏ các lệnh gọi thủ công notifyDataSetChanged hoặc findViewById.

Những điểm chính

  • Jetpack Compose — framework UI khai báo của Google cho Android bằng Kotlin (hàm @Composable thay vì bố cục XML).
  • @Composable — chú thích hàm mô tả một phần UI, có thể nhận tham số và đọc State.
  • State và MutableState — cơ chế phản ứng: khi State thay đổi, Compose chỉ tái tạo (recompose) các hàm Composable phụ thuộc.
  • remember — hàm lưu đệm giá trị giữa các lần tái tạo; nếu không có nó, State sẽ bị đặt lại mỗi lần cập nhật.
  • Modifier — chuỗi cấu hình (padding, size, clickable, background) kiểm soát giao diện và hành vi của một Composable.

Jetpack Compose là gì?

Jetpack Compose là framework UI của Google được xây dựng trên các nguyên tắc lập trình phản ứng. Thay vì Activity với bố cục XML, FragmentManager và ViewBinding, nhà phát triển mô tả giao diện thông qua các hàm Kotlin với chú thích @Composable. Compose không sử dụng LayoutInflater — UI là các hàm Kotlin thuần túy được biên dịch thành bytecode. Framework bao gồm nhiều thư viện: Compose UI (các thành phần cơ bản Text, Button, Column, Row), Compose Foundation (Material Design, Gestures, Focus), Compose Material3 (Material You với Dynamic Colors) và Compose Runtime (State, Side Effects, Coroutines). Compose hoạt động trên Android API 21+ (Android 5.0) và hoàn toàn tương thích với mã View/XML hiện có thông qua ComposeView — một bộ điều hợp AndroidView.

Compose so với View System

View System (2008) sử dụng hệ thống phân cấp đối tượng View với quản lý thủ công: nhà phát triển tạo bố cục XML, tìm Views qua findViewById, triển khai Adapter cho RecyclerView và gọi notifyDataSetChanged khi dữ liệu thay đổi. Compose mô tả UI một cách chức năng: khi trạng thái thay đổi, framework chỉ tái tạo các hàm Composable đã thay đổi, tính toán diff và áp dụng các thay đổi tối thiểu lên Canvas. Hiệu suất của Compose tương đương với View System và trong các tình huống có danh sách phức tạp (LazyColumn), nó thường vượt trội hơn RecyclerView nhờ bỏ qua các phần tử không cần thiết thông qua tham số key. Tại IT Sectr, Compose được sử dụng cho các mô-đun mới của ứng dụng Android với minSdk 24+.

Hàm Composable: khối xây dựng UI

@Composable — một chú thích biến một hàm Kotlin thông thường thành một khối xây dựng UI. Các hàm Composable có thể gọi các hàm Composable khác, tạo thành một cây thành phần. Không giống như View, các hàm Composable không có trạng thái mặc định — chúng không trạng thái (stateless) và được vẽ lại mỗi khi tham số đầu vào hoặc State thay đổi. Trình biên dịch Compose biến đổi các hàm @Composable thành mã có thể bị gián đoạn và tiếp tục (positional memoization) — điều này cho phép Compose chỉ khởi động lại các phần đã thay đổi mà không cần xây dựng lại toàn bộ cây.

kotlin
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
        )
    }
}

Hàm UserProfile nhận name và avatarUrl làm tham số, xây dựng một hàng với ảnh đại diện và tên. Modifier.fillMaxWidth() kéo dài thành phần ra toàn bộ chiều rộng, .padding(16.dp) thêm đệm. MaterialTheme.typography.titleMedium sử dụng kiểu hệ thống Material 3. Khi các tham số name hoặc avatarUrl thay đổi, Compose tái tạo UserProfile — tạo lại thành phần với các giá trị mới.

State và Recomposition trong Jetpack Compose

State trong Compose là bất kỳ giá trị nào mà sự thay đổi của nó kích hoạt tái tạo (khởi động lại) các hàm @Composable phụ thuộc. Cách tiếp cận cơ bản là mutableStateOf(), tạo ra MutableState<T> với hỗ trợ hệ thống snapshot của Compose. Snapshot là cơ chế theo dõi thay đổi: khi ghi vào State, Compose đánh dấu Snapshot hiện tại là dirty, và bộ lập lịch tái tạo chỉ khởi động lại các hàm Composable đang đọc State đó. Cho các bộ sưu tập có thể quan sát, hãy sử dụng mutableStateListOf() và mutableStateMapOf(). Compose hỗ trợ State từ các thành phần Lifecycle-Aware thông qua collectAsState() cho Kotlin Flow và observeAsState() cho LiveData.

kotlin
@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")
    }
}

Mã tạo một nút "Like" với trạng thái liked (Boolean) và count (Int) được lưu trữ qua mutableStateOf(). Khi nhấn, liked được đảo ngược và bộ đếm tăng/giảm — Compose tự động tái tạo LikeButton. Ủy quyền by cho phép sử dụng State như một biến thông thường: liked = !liked thay vì liked.value = !liked.value. Màu nút thay đổi phản ứng giữa primary (đã thích) và surfaceVariant (chưa thích).

remember: lưu đệm giữa các lần tái tạo

remember — một hàm Compose lưu đệm giá trị giữa các lần tái tạo. Nếu không có remember, mỗi lần khởi động lại hàm Composable tạo ra một trạng thái mới (mutableStateOf) — điều này phá vỡ logic ứng dụng: khi xoay màn hình hoặc thay đổi State cha, bộ đếm sẽ bị đặt lại. remember nhận một lambda tính toán và chỉ tính giá trị ở lần tạo đầu tiên; ở các lần sau, nó trả về kết quả đã lưu đệm. Để đặt lại bộ đệm, hãy sử dụng remember(key) — khóa xác định thời điểm tính lại giá trị. remember(key1, key2) tính lại khi bất kỳ khóa nào thay đổi. Cho các trạng thái tồn tại lâu dài (sống sót qua xoay màn hình), hãy sử dụng rememberSaveable — tương tự remember nhưng lưu vào Bundle thông qua SavedStateHandle.

kotlin
@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 bảo toàn seconds khi xoay màn hình (thay đổi cấu hình). LaunchedEffect khởi động một coroutine tăng seconds mỗi giây. Khi tái tạo TimerScreen (mỗi giây), seconds không bị đặt lại nhờ rememberSaveable. Sử dụng remember thông thường cho trạng thái không cần sống sót qua thay đổi cấu hình (ví dụ: cờ hoạt ảnh).

Modifier: chuỗi cấu hình Composable

Modifier — một đối tượng chứa bất biến triển khai mẫu Builder để cấu hình giao diện, hành vi và bố cục của các thành phần Composable. Mỗi lần gọi phương thức Modifier (.padding(), .width(), .clickable(), .background()) trả về một Modifier mới với phần tử được thêm vào. Thứ tự bổ từ quan trọng: .padding(16.dp).clickable { } — đệm được áp dụng trước trình xử lý nhấp, clickable theo dõi toàn bộ khu vực bao gồm cả đệm. .clickable { }.padding(16.dp) — toàn bộ khu vực trước đệm có thể nhấp được, đệm đẩy nội dung vào bên trong. Modifier hỗ trợ triển khai tùy chỉnh thông qua then(otherModifier) và compositionLocal để truy cập cấu hình cha.

kotlin
@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 khai báo cho Android với State và Modifier",
                style = MaterialTheme.typography.bodyMedium
            )
        }
    }
}

CardExample minh họa chuỗi Modifier: fillMaxWidth + padding + clickable. Card là một thành phần Material3 với cấu hình elevation và colors riêng. Column lồng nhau có đệm trong 16dp. Compose Material3 tự động điều chỉnh màu sắc theo Dynamic Color (Material You) trên Android 12+. Card là một trong hơn 30 thành phần Material3 được tích hợp trong Compose.

State hoisting và kiến trúc Compose

State hoisting — một mẫu nâng trạng thái ra khỏi hàm Composable lên nơi gọi nó, làm cho hàm không trạng thái (stateless). Một thành phần stateless nhận dữ liệu và callback thông qua tham số mà không tự sở hữu State. Điều này cải thiện khả năng tái sử dụng và kiểm thử: thành phần có thể được gọi với các State khác nhau và kiểm tra trong preview. Google khuyến nghị kiến trúc: ViewModel + StateFlow (hoặc MutableStateFlow) + collectAsState() trong Compose. ViewModel nâng trạng thái lên cấp màn hình, Compose hiển thị nó. Các hiệu ứng phụ (LaunchedEffect, DisposableEffect) xử lý các sự kiện một lần.

Thành phầnTrách nhiệmCông nghệ
ViewModelLưu trữ State, logic nghiệp vụStateFlow, MutableStateFlow
Screen ComposableTổ chức màn hình, State hoistingcollectAsState(), Scaffold, LazyColumn
Stateless ComponentUI không trạng thái, hiển thị thuần túyTham số @Composable + lambda
Side EffectHành động một lần (snackbar, điều hướng)LaunchedEffect, SnackbarHostState

Câu hỏi thường gặp

Jetpack Compose khác với bố cục XML như thế nào?

Bố cục XML có tính mệnh lệnh: LayoutInflater tải XML, findViewById tìm Views, nhà phát triển cập nhật văn bản/danh sách thủ công. Compose có tính khai báo: UI được mô tả bằng các hàm Kotlin @Composable và framework tự động vẽ lại chỉ những phần đã thay đổi khi State thay đổi. Compose giảm khối lượng mã UI xuống 30–50% và không sử dụng XML.

Tôi có cần thư viện riêng cho điều hướng trong Compose không?

Có, Google cung cấp Navigation Compose — một thư viện cho điều hướng khai báo giữa các màn hình. NavController quản lý ngăn xếp tuyến đường, composable() đăng ký màn hình, navArgument truyền tham số. Các lựa chọn thay thế: Voyager (cộng đồng) và Decompose (Badoo). Navigation Compose là tiêu chuẩn chính thức với hỗ trợ deep links và đối số type-safe.

Modifier trong Jetpack Compose là gì?

Modifier là một vùng chứa bất biến các mẫu trang trí (padding, size, clickable, background, border, clip) được áp dụng cho các thành phần Composable. Mỗi lần gọi trả về một Modifier mới với phần tử được thêm vào. Thứ tự quan trọng: .padding().clickable() áp dụng đệm trước khi nhấp, .clickable().padding() — ngược lại. Modifier là cách chính để tùy chỉnh các thành phần Compose.

Compose có hoạt động trên tất cả các phiên bản Android không?

Jetpack Compose hỗ trợ Android API 21+ (Android 5.0 Lollipop) thông qua Compose Compiler và Compose BOM. Material 3 (Dynamic Colors) khả dụng trên Android 12+; trên các phiên bản cũ hơn, bảng màu dự phòng được sử dụng. Cho các dự án mới, Google khuyến nghị minSdk 24+ (Android 7.0), được Compose hỗ trợ đầy đủ.

Làm thế nào để kiểm tra các thành phần Compose?

Google cung cấp Compose UI Test — một thư viện để kiểm tra trên JVM (Desktop) và trình giả lập. Các hàm chính: composeTestRule.setContent { } để hiển thị thành phần, onNodeWithText() để tìm phần tử, performClick()/performTextInput() cho các hành động. Kiểm tra Espresso tương thích với Compose thông qua ComposeTestRule, nhưng Compose UI Test là cách tiếp cận được ưa thích và nhanh hơn.

Tóm tắt

  • Jetpack Compose — framework UI khai báo của Google cho Android với các hàm Kotlin @Composable thay vì XML (ổn định từ 2021).
  • @Composable — chú thích biến hàm Kotlin thành thành phần UI; cây hàm Composable thay thế hệ thống phân cấp View.
  • State và mutableStateOf — nền tảng phản ứng của Compose thông qua hệ thống Snapshot; tái tạo chỉ ảnh hưởng đến các hàm phụ thuộc.
  • remember lưu đệm giá trị giữa các lần tái tạo; rememberSaveable bảo toàn State khi thay đổi cấu hình.
  • Modifier — chuỗi cấu hình (padding, size, clickable, background) tạo thành vùng chứa bất biến; thứ tự bổ từ quan trọng.
  • State hoisting — mẫu nâng trạng thái lên cho các thành phần stateless; ViewModel + StateFlow + collectAsState() là kiến trúc được khuyến nghị.
  • Material 3 với Dynamic Colors (Android 12+) là chủ đề tiêu chuẩn của Compose với khả năng tự động thích ứng với hình nền thiết bị.

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm