Jetpack Compose trong phát triển di động: nó là gì, các khái niệm chính và cách hoạt động

Tác giả: IT Sectr Đã đăng: 2026-07-05 Thời gian đọc: 10 phút
Jetpack Compose — framework UI hiện đại cho Android của Google. Theo Google Compose Docs (2025), Compose được sử dụng trong 60% dự án Android mới. Hiểu về @Composable, Recomposition và State Hoisting là nền tảng để làm việc hiệu quả với Compose.

Những điểm chính

  • @Composable — chú thích cho hàm UI. Composition — gọi các hàm Composable. Recomposition — khởi động lại khi trạng thái thay đổi.
  • State Hoisting — nâng trạng thái lên cha. State down, events up. Các thành phần tái sử dụng và kiểm thử được.
  • remember + mutableStateOf — trạng thái cục bộ. remember giữ giá trị giữa các lần tái hợp.
  • Modifier — chuỗi bổ nghĩa (padding, size, clickable). Thứ tự quan trọng.
  • NavController + NavHost — điều hướng. LaunchedEffect/DisposableEffect — hiệu ứng phụ.

Cơ bản về Jetpack Compose (@Composable, Composition, Recomposition)

@Composable — chú thích biến hàm thành Composable. Hàm Composable là khối xây dựng UI. Chúng không trả về View mà phát ra các phần tử vào Composition. Composition — cây UI được xây dựng từ các lời gọi hàm Composable. Compose so sánh cây mới với cây cũ và chỉ cập nhật các phần đã thay đổi.

Recomposition

Recomposition — khởi động lại hàm Composable khi trạng thái thay đổi. Compose theo dõi trạng thái nào được đọc trong mỗi hàm. Khi trạng thái thay đổi, Compose chỉ khởi động lại các hàm đọc trạng thái đó (Smart Recomposition). Recomposition lạc quan: có thể chạy nhiều lần, vì vậy hàm phải thuần túy (không có hiệu ứng phụ). Hiệu ứng phụ đặt trong LaunchedEffect hoặc DisposableEffect. Hàm Composable không thể là suspend. Chúng được gọi từ các hàm Composable khác. Thứ tự gọi không được đảm bảo (Compose có thể sắp xếp lại).

kotlin
// Ví dụ Composable với State Hoisting và LazyColumn
@Composable
fun ItemList(
    items: List<String>,
    onItemClick: (String) -> Unit
) {
    LazyColumn(
        modifier = Modifier.fillMaxSize()
    ) {
        items(items) { item ->
            Card(
                modifier = Modifier
                    .fillMaxWidth()
                    .clickable { onItemClick(item) }
                    .padding(8.dp)
            ) {
                Text(
                    text = item,
                    style = MaterialTheme.typography.bodyLarge
                )
            }
        }
    }
}

@Composable
fun MainScreen() {
    var text by remember { mutableStateOf("") }
    val items = listOf("Item 1", "Item 2", "Item 3")

    Scaffold(
        topBar = {
            TopAppBar(title = { Text("Compose App") })
        }
    ) { padding ->
        ItemList(
            items = items,
            onItemClick = { selected -> text = selected }
        )
    }
}

Composition — cây khai báo. Recomposition — khởi động lại thông minh. IT Sectr khuyên bạn nên theo dõi độ ổn định của kiểu — kiểu không ổn định gây ra tái hợp quá mức.

CompositionLocal

CompositionLocal — truyền dữ liệu ngầm trong Compose. Tương tự @Environment trong SwiftUI. CompositionLocalProvider — đặt giá trị. current — đọc. Được sử dụng cho: Theme (MaterialTheme), ContentScale, Density. CompositionLocal tĩnh — cho cấu hình không thay đổi. CompositionLocal động — cho giá trị có thể thay đổi (chủ đề). IT Sectr khuyên dùng CompositionLocal cho cấu hình toàn cục và tham số rõ ràng cho dữ liệu.

Trạng thái (remember, mutableStateOf, State Hoisting)

remember — giữ giá trị giữa các lần tái hợp. mutableStateOf — tạo trạng thái có thể quan sát (MutableState<T>). Khi thay đổi, kích hoạt tái hợp. State Hoisting — mẫu: trạng thái được nâng lên thành phần cha, con nhận giá trị + callback. State (bất biến) — chỉ đọc. MutableState — đọc + ghi. rememberSaveable — tồn tại khi xoay màn hình/kết thúc tiến trình.

State Hoisting

State Hoisting — nguyên tắc: state down, events up. Trạng thái được lưu trong cha và truyền cho thành phần con qua tham số. Thành phần con báo cáo thay đổi qua lambda (callback). Lợi ích: tái sử dụng, kiểm thử được, nguồn sự thật duy nhất. Ví dụ: thay vì MyTextField lưu trạng thái riêng, cha lưu chuỗi và truyền qua value + onValueChange.

Trạng thái dẫn xuất

derivedStateOf — trạng thái tính toán, chỉ tính lại khi phụ thuộc thay đổi. Được sử dụng cho lọc, chuyển đổi, xác thực. snapshotFlow — chuyển State thành Flow. Được sử dụng cho chuỗi phản ứng. collectAsState — thu thập Flow thành State trong Composable. IT Sectr khuyên dùng derivedStateOf cho giá trị tính toán và snapshotFlow để kết nối State với coroutines.

Bộ chứa (Column, Row, Box, LazyColumn)

Column — bố cục dọc (tương tự LinearLayout dọc). Row — bố cục ngang. Box — bố cục xếp chồng (tương tự FrameLayout). LazyColumn — danh sách dọc có thể cuộn với tải lười. LazyRow — danh sách ngang có thể cuộn. Scaffold — khung màn hình chính: TopAppBar, BottomBar, FloatingActionButton, Snackbar. TopAppBar — thanh trên cùng. BottomNavigation — điều hướng dưới cùng (NavigationBar trong Material 3). Modifier — chuỗi: .fillMaxWidth().padding(8.dp).clickable { }. Thứ tự bổ nghĩa quan trọng — mỗi cái tạo một wrapper mới.

Tối ưu LazyColumn

LazyColumn — danh sách ảo hóa. Chỉ hiển thị phần tử nhìn thấy. Tối ưu: 1) key — khóa duy nhất cho mục, 2) contentType — nhóm mục theo loại, 3) itemContent — giảm thiểu tái hợp trong mục, 4) LazyVerticalGrid / LazyHorizontalGrid — cho lưới. LazyLayout — bố cục lười tùy chỉnh. Paging 3 + Compose — phân trang qua collectAsLazyPagingItems. IT Sectr khuyên dùng key(item) cho mọi LazyColumn để tái hợp có thể dự đoán.

Navigation Compose — thư viện điều hướng. NavController — quản lý ngăn xếp đích. NavHost — bộ chứa đồ thị điều hướng. composable("route") — đăng ký đích. navController.navigate("route") — điều hướng. popBackStack() — quay lại. Đối số: composable("detail/{id}", arguments = listOf(navArgument("id") { type = NavType.StringType })). Deep linking qua intentFilter. BottomNavigation — tích hợp với NavController: NavBarItem → navigate + popUpTo.

Nhiều ngăn xếp quay lại — ngăn xếp quay lại riêng cho mỗi tab BottomNavigation. SavedStateHandle — giữ đối số khi kết thúc tiến trình. NavArgs — đối số an toàn kiểu (Kotlin 2.0+). Deep links — lược đồ URL cho liên kết ngoài. Cử chỉ quay lại dự đoán (Android 14+) — hỗ trợ cử chỉ quay lại với xem trước. IT Sectr khuyên dùng NavArgs cho an toàn kiểu và nhiều ngăn xếp quay lại cho BottomNavigation.

Hiệu ứng (LaunchedEffect, DisposableEffect)

LaunchedEffect — chạy khối suspend trong Composition. Bị hủy khi rời Composition. Khởi động lại khi keys thay đổi. Được sử dụng cho: tải dữ liệu, bộ đếm thời gian, hoạt ảnh. DisposableEffect — cho tài nguyên cần dọn dẹp: onDispose { } — hủy đăng ký listener, đóng kết nối. SideEffect — hiệu ứng đồng bộ (mỗi lần tái hợp). Được sử dụng cho: ghi log, đồng bộ với mã không Compose. IT Sectr khuyên dùng LaunchedEffect cho tải dữ liệu và DisposableEffect cho dọn dẹp.

Tham số Jetpack Compose SwiftUI
Mô tả UIHàm @Composable + ModifierView Protocol + @ViewBuilder
Trạng tháiremember + mutableStateOf@State, @StateObject
Nâng trạng tháiState Hoisting@Binding
Danh sáchLazyColumnList
Điều hướngNavController + NavHostNavigationStack (iOS 16+)
Hiệu ứngLaunchedEffect, DisposableEffect.task{}, .onAppear{}
Bố cụcColumn, Row, BoxVStack, HStack, ZStack

Compose — hàm + bổ nghĩa. SwiftUI — struct + bổ nghĩa. Các khái niệm tương tự, cú pháp khác nhau. IT Sectr khuyên học cả hai framework — hiểu một cái giúp học cái kia dễ dàng hơn.

Mẫu hiệu ứng

rememberCoroutineScope — truy cập CoroutineScope bên ngoài LaunchedEffect (ví dụ: khi nhấp nút). snapshotFlow — chuyển State thành Flow cho chuỗi. produceState — chuyển nguồn không Compose thành State. animateFloatAsStateanimateColorAsState — hoạt ảnh qua hiệu ứng. IT Sectr khuyên dùng rememberCoroutineScope cho sự kiện UI và LaunchedEffect cho tải tự động.

Chủ đề (MaterialTheme, Material3)

MaterialTheme — chủ đề toàn cục của Compose. Màu sắc, kiểu chữ, hình dạng. MaterialTheme { } — bao bọc toàn bộ ứng dụng. Material3 (M3) — hệ thống thiết kế Google 2023+. Dynamic Colors — thích ứng với hình nền (Android 12+). TextStyle — cấu hình văn bản: fontSize, fontWeight, lineHeight. Shape — làm tròn góc. Elevation — đổ bóng. IT Sectr khuyên dùng Material3 mặc định và Dynamic Colors cho thiết bị hiện đại.

kotlin
@Composable
fun AppTheme(content: @Composable () -> Unit) {
    val colorScheme = if (isSystemInDarkTheme()) {
        darkColorScheme(
            primary = Color(0xFFBB86FC),
            secondary = Color(0xFF03DAC6)
        )
    } else {
        lightColorScheme(
            primary = Color(0xFF6200EE),
            secondary = Color(0xFF03DAC6)
        )
    }
    MaterialTheme(
        colorScheme = colorScheme,
        typography = Typography(
            bodyLarge = TextStyle(fontSize = 16.sp)
        )
    ) { content() }
}

Hoạt ảnh (animate*, AnimatedVisibility)

animateFloatAsState — tạo hoạt ảnh giá trị Float. animateColorAsState — tạo hoạt ảnh màu sắc. animateDpAsState — tạo hoạt ảnh kích thước. AnimatedVisibility — hiện/ẩn với .animateEnterExit(). AnimatedContent — hoạt ảnh khi nội dung thay đổi (crossfade, slide). updateTransition — hoạt ảnh dựa trên trạng thái enum. Animatable — hoạt ảnh tùy chỉnh qua giao diện Animatable. IT Sectr khuyên dùng AnimatedVisibility cho danh sách và AnimatedContent cho chuyển màn hình.

kotlin
@Composable
fun AnimatedCounter(count: Int) {
    val animatedCount by animateFloatAsState(
        targetValue = count.toFloat(),
        animationSpec = spring(
            dampingRatio = Spring.DampingRatioMediumBouncy,
            stiffness = Spring.StiffnessLow
        )
    )

    AnimatedContent(targetState = count) { targetCount ->
        Text(
            text = "$targetCount",
            style = MaterialTheme.typography.displayLarge,
            modifier = Modifier.animateContentSize()
        )
    }
}

Kiểm thử (Compose UI Test)

Compose UI Test — kiểm thử màn hình Compose. createComposeRule() — quy tắc JUnit. setContent { } — đặt Composable. onNodeWithText, onNodeWithTag, onNodeWithContentDescription — tìm phần tử. performClick, performTextInput, performScrollTo — hành động. assertIsDisplayed, assertTextEquals — khẳng định. Semantics — cây Semantics cho trợ năng và kiểm thử. IdlingResource — chờ thao tác bất đồng bộ. Kiểm thử ảnh chụp màn hình — Papercuts, Roborazzi. IT Sectr khuyên kiểm thử UI cho mỗi màn hình và kiểm thử đơn vị cho ViewModel.

WindowSizeClass — thích ứng với kích thước màn hình (Compact, Medium, Expanded). Liên quan đến bố cục đáp ứng Material3. Được sử dụng trong Adaptive Navigation Suite để tự động chuyển từ BottomNavigation sang NavigationRail. IT Sectr khuyên dùng WindowSizeClass cho thích ứng Compose trên máy tính bảng và máy tính để bàn.

Paging 3 + Compose — thư viện phân trang của Google. PagingData — luồng trang. PagingConfig — cài đặt (pageSize, prefetchDistance). collectAsLazyPagingItems() — thu thập trong Compose. PagingSource — nguồn tùy chỉnh. RemoteMediator — tải kết hợp (mạng + DB). Paging 3 là tiêu chuẩn cho danh sách cuộn vô hạn trong Compose.

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

@Composable trong Jetpack Compose là gì?

@Composable — chú thích cho hàm UI. Các lời gọi hàm Composable tạo thành Composition. Recomposition — khởi động lại khi trạng thái thay đổi.

State Hoisting trong Compose là gì?

State Hoisting — nâng trạng thái lên cha. State down, events up. Các thành phần tái sử dụng và kiểm thử được.

Recomposition trong Jetpack Compose là gì?

Recomposition — khởi động lại hàm Composable khi trạng thái thay đổi. Smart Recomposition — tập hàm tối thiểu.

NavController và NavHost hoạt động như thế nào?

NavController — ngăn xếp đích. NavHost — bộ chứa đồ thị. composable("route") — đăng ký. navigate() — chuyển tiếp.

Sự khác biệt giữa LaunchedEffect và DisposableEffect là gì?

LaunchedEffect — khối suspend với hủy tự động. DisposableEffect — tài nguyên với dọn dẹp onDispose.

Tóm tắt

  • @Composable — hàm UI. Composition — cây UI. Recomposition — khởi động lại thông minh.
  • remember + mutableStateOf — trạng thái cục bộ. rememberSaveable — cho xoay màn hình.
  • State Hoisting — state down, events up. Nền tảng của thành phần tái sử dụng.
  • Modifier — chuỗi (thứ tự quan trọng). Column, Row, Box — bộ chứa cơ bản.
  • LazyColumn — danh sách hiệu quả. Scaffold — khung màn hình (TopBar, BottomBar, FAB).
  • NavController + NavHost — điều hướng. composable() — tuyến đường. navigate() — chuyển tiếp.
  • LaunchedEffect — hiệu ứng bất đồng bộ. DisposableEffect — dọn dẹp. SideEffect — đồng 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