Jetpack Compose là gì? Xây giao diện Android bằng code Kotlin

  • author-image

    Nguyễn Đình Cường

  • blog-tag
  • blog-comment 0 comment
  • created-date 09 Nov, 2026
blog-thumbnail

Trước đây giao diện Android thường được mô tả bằng file XML rồi gắn với code Kotlin hoặc Java. Jetpack Compose thay đổi cách làm đó: bạn viết giao diện ngay trong Kotlin theo kiểu khai báo. Bài viết giới thiệu các khái niệm nền tảng để bạn bắt đầu.

Compose là gì?

Jetpack Compose là bộ công cụ hiện đại của Google để xây giao diện Android. Thay vì tạo và sửa các đối tượng View, bạn mô tả giao diện nên trông thế nào ứng với dữ liệu hiện tại. Khi dữ liệu đổi, Compose tự cập nhật phần giao diện bị ảnh hưởng. Đây gọi là lập trình giao diện khai báo.

Hàm Composable

Đơn vị cơ bản là hàm có chú thích @Composable. Mỗi hàm mô tả một phần giao diện và có thể được ghép lồng nhau.

@Composable
fun Greeting(name: String) {
    Text(text = "Xin chào, $name!")
}

@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
    Greeting("Bem")
}

Chú thích @Preview cho phép xem trước giao diện ngay trong Android Studio mà không cần chạy máy ảo.

Bố cục: Row, Column, Box

@Composable
fun ProfileCard(name: String, role: String) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(16.dp),
        verticalAlignment = Alignment.CenterVertically
    ) {
        Icon(Icons.Default.Person, contentDescription = null)
        Spacer(Modifier.width(12.dp))
        Column {
            Text(name, style = MaterialTheme.typography.titleMedium)
            Text(role, style = MaterialTheme.typography.bodySmall)
        }
    }
}

Column xếp dọc, Row xếp ngang, Box xếp chồng. Mọi tùy chỉnh kích thước, khoảng cách, nền, sự kiện chạm đều đi qua Modifier, và thứ tự các modifier có ý nghĩa.

State và recomposition

Khi state thay đổi, các composable đọc state đó được gọi lại; quá trình này gọi là recomposition. Để giữ giá trị qua các lần vẽ lại, dùng remember cùng mutableStateOf:

@Composable
fun Counter() {
    var count by remember { mutableStateOf(0) }

    Column(horizontalAlignment = Alignment.CenterHorizontally) {
        Text("Đã bấm $count lần")
        Button(onClick = { count++ }) {
            Text("Tăng")
        }
    }
}

Nếu thiếu remember, biến sẽ bị đặt lại về 0 mỗi lần vẽ lại.

State hoisting: nâng state lên

Một nguyên tắc quan trọng là để composable không tự giữ state mà nhận giá trị và hàm xử lý sự kiện từ bên ngoài. Cách này làm composable dễ tái sử dụng và dễ kiểm thử:

@Composable
fun NameField(value: String, onValueChange: (String) -> Unit) {
    OutlinedTextField(
        value = value,
        onValueChange = onValueChange,
        label = { Text("Họ tên") }
    )
}

Danh sách với LazyColumn

@Composable
fun UserList(users: List<String>) {
    LazyColumn {
        items(users) { user ->
            Text(user, modifier = Modifier.padding(12.dp))
        }
    }
}

LazyColumn chỉ tạo các phần tử đang hiển thị, tương đương RecyclerView nhưng gọn hơn rất nhiều.

Ưu và nhược điểm

  • Ưu: ít code hơn, không cần XML, xem trước trực tiếp, dễ làm giao diện động và hiệu ứng, tích hợp tốt với Material Design.
  • Nhược: tư duy khai báo cần thời gian làm quen, khi tối ưu phải hiểu recomposition, và dự án cũ vẫn có thể dùng View truyền thống nên đôi khi phải kết hợp cả hai.

Lộ trình làm quen

  1. Nắm cơ bản Kotlin, đặc biệt lambda.
  2. Làm các bố cục đơn giản với Row, Column, Modifier.
  3. Học state, remember và state hoisting.
  4. Kết hợp ViewModel và điều hướng Compose.

Kết luận

Compose là hướng đi chính cho giao diện Android mới. Khi đã quen với tư duy khai báo, bạn sẽ thấy việc dựng và sửa giao diện nhanh và ít lỗi hơn nhiều. Hãy thử dựng lại một màn hình quen thuộc để cảm nhận.

Những bẫy hiệu năng thường gặp trong Compose

Compose vẽ lại phần giao diện đọc state đã thay đổi, nhưng bạn vẫn có thể vô tình làm nó vẽ lại quá nhiều. Một nguyên nhân là tạo đối tượng mới ở mỗi lần vẽ, như danh sách hay lambda, khiến Compose coi tham số đã đổi. Dùng remember để giữ các giá trị tốn kém, và đặt key ổn định cho các mục trong LazyColumn để thư viện tái sử dụng đúng phần tử khi danh sách thay đổi.

Một bẫy khác là đọc state quá sớm ở composable cha, làm cả nhánh con bị vẽ lại khi chỉ một phần nhỏ cần thay đổi. Hãy đẩy việc đọc state xuống sát nơi dùng. Luôn đo bằng bản release vì bản debug chậm hơn nhiều, và dùng công cụ Layout Inspector cùng bộ đếm recomposition trong Android Studio để thấy composable nào đang bị gọi lại nhiều bất thường.

Compose và ứng dụng sẵn có

Bạn không cần viết lại cả ứng dụng để dùng Compose. Có thể nhúng ComposeView vào bố cục XML hiện có, hoặc nhúng View cũ vào Compose bằng AndroidView. Nhờ vậy dự án lớn chuyển dần từng màn hình. Hãy bắt đầu bằng các màn hình mới hoặc những phần đơn giản như thẻ, hộp thoại để làm quen trước khi động vào các màn hình phức tạp.

Để học Compose cùng Kotlin theo lộ trình rõ ràng, bạn có thể tham khảo khóa học lập trình di động trên codebem.com.

author_photo
Nguyễn Đình Cường

0 comment