Tin tức về sản phẩm

Tính năng mới trong bản phát hành Jetpack Compose tháng 8 năm 2026

5 phút đọc
Xem hồ sơ của Nick Butcher
Nick Butcher Nhà quản lý sản phẩm

Hôm nay, bản phát hành Jetpack Compose tháng 8 năm 2026 đã ổn định! Bản phát hành này mang đến phiên bản 1.12 trên các mô-đun Compose cốt lõi (xem ánh xạ BOM đầy đủ), giới thiệu các API trực quan phong phú như Mesh Gradients và hỗ trợ Gamut màu rộng (WCG), các tính năng bố cục cấu trúc như các vùng được đặt tên trong Grid, tích hợp liền mạch với Trình quản lý thông tin xác thực của Android, cũng như những điểm cải tiến đáng kể về hiệu suất và kiểm thử.

Để cập nhật dự án lên bản phát hành hôm nay, hãy nâng cấp phiên bản Bảng kê khai thành phần (BOM) của Compose lên 2026.08.00:

implementation(platform("androidx.compose:compose-bom:2026.08.00"))

Thay đổi có thể gây lỗi

  • AGP và Compile SDK: Compose 1.12 cập nhật compileSdk lên API 37, yêu cầu AGP tối thiểu là 9.1.2. Xin lưu ý rằng Compose sẽ luôn nhắm đến compileSdk mới nhất. Tìm hiểu thêm về thay đổi này tại đây.
  • Modifier.onFirstVisible() không được dùng nữa: Di chuyển đến Modifier.onVisibilityChanged(). Hàm này cung cấp tính năng theo dõi ngưỡng hiển thị chính xác hơn.

Đồ hoạ

Lưới chuyển màu

Compose 1.12 giới thiệu MeshGradientPainter để giúp bạn tạo các chuyển màu tự nhiên có nhiều điểm.

meshGradient.gif
val rows = 1
val columns = 1

val gradientPainter = remember {
    MeshGradientPainter(rows, columns) {
        // Parameters: row, column, position, color
        setVertex(0, 0, Offset(0f, 0f), Color.Red)     // Top-Left
        setVertex(0, 1, Offset(1f, 0f), Color.Blue)    // Top-Right
        setVertex(1, 0, Offset(0f, 1f), Color.Green)   // Bottom-Left
        setVertex(1, 1, Offset(1f, 1f), Color.Yellow)  // Bottom-Right
    }
}

Box(
    modifier = modifier
        .aspectRatio(16/9f)
        .fillMaxWidth()
        .paint(gradientPainter)
)

Để biết thêm thông tin và ví dụ, hãy xem tài liệu.

Gam màu rộng và hỗ trợ HDR

Màn hình hiện đại mang đến độ trung thực về màu sắc cao hơn và dải tương phản động cao hơn. Trong Compose 1.12, chúng tôi đã bật tính năng hỗ trợ toàn bộ quy trình cho Gam màu rộng (P3) và khả năng kết xuất HDR trên đồ hoạ, màu vẽ và chương trình đổ bóng của Compose. Màu được xác định trong các không gian màu không phải sRGB (chẳng hạn như Display P3) được giữ nguyên cho đến khi kết xuất nền tảng mà không cần kẹp màu. Màu sắc sẽ chuyển về sRGB một cách an toàn nếu sử dụng một không gian màu không được hỗ trợ (ví dụ: CieXyz, CieLab hoặc Oklab), dựa vào một không gian màu trên một phiên bản Android không được hỗ trợ (ví dụ: Bt2020Hlg trên Android 13 trở xuống) hoặc nếu ứng dụng đang chạy trên Android 9 (API 28) trở xuống.

Các thay đổi đáng chú ý khác:

  • LayerOutsets đã được thêm vào GraphicsLayer và Modifier.graphicsLayer. Bạn có thể dùng thuộc tính này để tăng ranh giới hiển thị của lớp vượt quá kích thước đo được. Áp dụng LayerOutsets để tránh hành vi clipToBounds ngầm khi lớp được chuyển thành vùng đệm ngoài màn hình.

Kiểu

Tại Google I/O, chúng tôi đã chia sẻ tầm nhìn ban đầu của mình về Styles API của Compose – một cách thức hợp nhất và hiệu quả để tạo kiểu cho các thành phần. Kể từ đó, chúng tôi đã tiếp tục xây dựng cấu trúc cơ bản để đảm bảo tính an toàn về kiểu nghiêm ngặt và độ chính xác có thể dự đoán, đồng thời hỗ trợ xây dựng các hệ thống thiết kế tuỳ chỉnh. 

Để đảm bảo chúng tôi có được lớp cơ sở này một cách chính xác, API sẽ vẫn ở trạng thái thử nghiệm và bạn có thể gặp phải các thay đổi mang tính đột phá. 

Tối ưu hoá thời gian chạy

Keyed SideEffect Overload

SideEffect hiện hỗ trợ các đối số khoá, cho phép bạn kích hoạt các hiệu ứng phụ một lần bất cứ khi nào các khoá cụ thể thay đổi. Điều này có thể giúp cải thiện hiệu suất so với việc sử dụng LaunchedEffect hoặc DisposableEffect khi bạn không cần khối đồng thời hoặc khối loại bỏ. SideEffect nhanh hơn LaunchedEffect đến 90% và nhanh hơn DisposableEffect khoảng 20%. Lưu ý rằng SideEffect chạy hiệu ứng trước DisposableEffect và LaunchedEffect, vì vậy, hãy thận trọng nếu di chuyển các hiệu ứng hiện có sang API này, đặc biệt là đối với LaunchedEffects dựa vào việc được gửi đi để bắt đầu sau khi khung hình hiện tại hoàn tất. 

@Composable
fun AnalyticsTracker(userId: String, screenName: String) {
    SideEffect(key1 = userId, key2 = screenName) {
        analytics.logScreenView(userId, screenName)
    }
}

Ảnh động

Chuyển cảnh tương tác gồm 2 giai đoạn

  • Thành phần kết hợp mới: DeferredAnimatedContent và DeferredAnimatedVisibility cho phép tạo hiệu ứng chuyển đổi hai giai đoạn thú vị, chẳng hạn như để theo dõi cử chỉ xem trước thao tác quay lại.
  • Kiểm soát ảnh động theo cách thủ công: Trong giai đoạn trì hoãn của quá trình chuyển đổi, các thuộc tính có ảnh động (chẳng hạn như tỷ lệ hoặc độ lệch) hiện có thể được điều chỉnh theo cách thủ công theo thời gian thực (ví dụ: theo dõi cử chỉ vuốt).
  • Bàn giao liền mạch: Sau khi giai đoạn hoãn lại kết thúc, công cụ chuyển đổi sẽ tiếp quản và thực hiện quy trình bàn giao liền mạch (bao gồm cả chuyển tốc độ) sang quá trình chuyển đổi tự động.
  • Hỗ trợ phần tử dùng chung: Cờ permitTransformDuringDeferredTransition mới trong SharedContentConfig sẽ kiểm soát việc các phần tử dùng chung có biến đổi trực quan cùng với các vùng chứa mẹ trong giai đoạn chuyển đổi bị hoãn hay không.
val state = remember { DeferredTransitionState(initialScreen) }
val transition = rememberDeferredTransition(state)

if (predictiveBackInProgress) {
    state.defer(targetScreen)
} else {
    state.animateTo(targetScreen)
}

transition.DeferredAnimatedContent(
    targetState = targetScreen,
    mutableTransformSpec = {
       MutableContentTransform {
           // Manually manipulate properties during the deferred phase
           initialContentTransform { scale = swipeProgress }
       }
    }
) { screen ->
    ScreenContent(screen)
}

Dưới đây là 2 bản minh hoạ về các trường hợp sử dụng trong đó ảnh động dựa trên cử chỉ được chuyển sang ảnh động được kích hoạt:

colorCards.gif

Văn bản, dữ liệu đầu vào và tích hợp nền tảng

Định dạng văn bản có thể chỉnh sửa

Các API mới cung cấp tính năng định dạng văn bản đa dạng thức cho văn bản có thể chỉnh sửa trong BasicTextField. Giờ đây, bạn có thể áp dụng và thao tác với định dạng ký tự và đoạn văn bản nội tuyến theo phương thức lập trình bằng cách sử dụng SpanStyle và ParagraphStyle thông qua phương thức addStyle() mới trong phạm vi TextFieldBuffer (chẳng hạn như trong textFieldState.edit { ... } hoặc InputTransformation). Ngoài ra, TextFieldBuffer cung cấp các API getSpanStyles() và getParagraphStyles() trả về các đối tượng TrackedRange, cho phép bạn đọc, cập nhật hoặc xoá các kiểu đã áp dụng. Để bổ sung cho việc tạo định dạng, TextFieldState hiện hiển thị một thuộc tính textStyles chỉ đọc để truy vấn các kiểu đang hoạt động trên các dải ô, trong khi TextFieldBuffer cung cấp originalTextStyles để kiểm tra trạng thái định dạng trước khi chỉnh sửa. Định dạng văn bản và chú giải tuỳ chỉnh được duy trì trong các thay đổi về cấu hình.

val state = rememberTextFieldState("Formatted text in Compose 1.12")

// Apply bold and color styles to a range of text
state.edit {
    addStyle(
        SpanStyle(fontWeight = FontWeight.Bold, color = Color.Blue),
        start = 0,
        end = 9
    )
}

// Query active styles from TextFieldState
val currentStyles = state.textStyles

Chọn văn bản

API SelectionState mới cung cấp khả năng kiểm soát và khả năng ghi nhận theo chương trình đối với việc chọn văn bản trong SelectionContainer. Việc lưu trữ một đối tượng SelectionState thông qua rememberSelectionState() và truyền vào SelectionContainer sẽ hiển thị selectedTexts dưới dạng một danh sách phản ứng của AnnotatedStrings và cung cấp các phương thức như selectAll(), clear(), select(TextRange) và extendSelectionByWord().

Ngoài ra, hãy dùng getSelectableTexts() để truy xuất tất cả các mục văn bản có thể chọn theo thứ tự bố cục và chọn văn bản trên các thành phần kết hợp trong SelectionContainer bằng cách sử dụng một phạm vi toàn cục. 

@Composable
fun ProgrammaticSelectionExample() {
    val selectionState = rememberSelectionState()

    Column {
        Button(
            onClick = { selectionState.selectAll() },
            modifier = Modifier.disableSelectionClearOnTap()
        ) {
            Text("Select All")
        }

        SelectionContainer(state = selectionState) {
            Text("Text content to be selected programmatically.")
        }
    }
}

Tích hợp Trình quản lý thông tin xác thực

Giờ đây, các trường văn bản Compose được tích hợp nguyên bản với Trình quản lý thông tin xác thực của Android (API 34 trở lên) thông qua khung Tự động điền (API dưới 34 được xử lý bằng androidx.credentials library). Bằng cách đính kèm thuộc tính ngữ nghĩa credentialRequest mới với CredentialRequestData, các dữ liệu đầu vào văn bản có thể nhắc khoá truy cập, thông tin đăng nhập đã lưu hoặc yêu cầu đăng nhập ngay trong quy trình nhập dữ liệu của người dùng.

@Composable
fun LoginField(textFieldState: TextFieldState) {
    val credentialData = remember {
        CredentialRequestData(
            // Specify Credential Manager request options
        )
    }

    BasicTextField(
        state = textFieldState,
        modifier = Modifier.semantics {
            credentialRequest = credentialData
        }
    )
}

Các thay đổi đáng chú ý khác:

  • Hỗ trợ các chế độ cài đặt biến thể phông chữ trong phông chữ có thể tải xuống.
  • Bật tính năng tự động cuộn khi kéo phần văn bản được chọn ra ngoài khung hiển thị trong SelectionContainer.
  • Đã thêm chế độ hỗ trợ cho âm thanh tương tác tự động (lượt nhấp và thao tác điều hướng bằng tiêu điểm) vào các thành phần Compose, cùng với thành phần kết hợp SoundEffectOnInteraction mới để cho phép chọn không sử dụng. Xin lưu ý rằng do thay đổi này, giờ đây, các trình nghe lượt nhấp ngữ nghĩa phải được gọi từ luồng chính, điều này có thể ảnh hưởng đến một số ít trường hợp kiểm thử.
  • KeyboardType hiện bao gồm Date, Time, DateTime và SignedDecimal.
  • BasicSecureTextField hiện sử dụng TextObfuscationMode.System theo mặc định, trong khi RevealLastTyped đóng vai trò là một chế độ ghi đè tuyệt đối.

Cải tiến bố cục

Vùng có tên trong bố cục lưới

Giờ đây, bạn có thể dễ dàng tạo các bố cục 2D phức tạp bằng các vùng có tên trong thành phần @Experimental Lưới. Thay vì quản lý chỉ mục cột và hàng dạng số trên các mục, bạn có thể xác định các vùng ngữ nghĩa trong GridConfigurationScope và định vị các thành phần kết hợp theo tên vùng.

@OptIn(ExperimentalGridApi::class)
@Composable
fun DashboardLayout() {
    Grid(
        config = {
            area("header", row = 0, column = 0, rowSpan = 1, columnSpan = 2)
            area("sidebar", row = 1, column = 0)
            area("content", row = 1, column = 1)
            gap(16.dp)
        }
    ) {
        HeaderSection(modifier = Modifier.gridItem(areaId = "header"))
        NavigationSidebar(modifier = Modifier.gridItem(areaId = "sidebar"))
        MainContentView(modifier = Modifier.gridItem(areaId = "content"))
    }
}

Để biết thêm thông tin, hãy xem tài liệu.

Hiệu suất

Như mọi bản phát hành khác, chúng tôi tiếp tục đầu tư vào hiệu suất của Compose để đảm bảo rằng khung này giúp bạn tạo ra những ứng dụng đẹp mắt và hiệu quả. Trong bản phát hành này, chúng tôi tập trung vào việc cải thiện hiệu suất khởi động và hiện đang thấy Thời gian hiển thị khung hình đầu tiên (thời gian cần thiết để một ứng dụng tạo khung hình đầu tiên) tương đương với Khung hiển thị trong các phép đo điểm chuẩn của chúng tôi.

timetoinitialdisplay@2x _v2.png

Nâng cấp hoạt động kiểm thử và công cụ

Kiểm thử đồng bộ hoá

Compose 1.12 giới thiệu các API kiểm thử mới được thiết kế để giảm thời gian thực thi kiểm thử và loại bỏ tình trạng không ổn định trong quá trình lấy mẫu trạng thái:

  • hasPendingWork: Thụ động kiểm tra xem giao diện người dùng có công việc đang chờ xử lý hay không mà không cần chuyển đồng hồ, đây là lựa chọn lý tưởng cho các vòng lặp ảnh động thủ công.
  • runWithoutImplicitWait: Tạm thời vô hiệu hoá tính năng đồng bộ hoá ngầm khi thực hiện từng bước qua các khung đồng hồ thủ công (ví dụ: kiểm thử ảnh động).
@Test
fun testAnimationStateFast() {

composeTestRule.mainClock.autoAdvance = false
    
    while (composeTestRule.hasPendingWork()) {
        composeTestRule.mainClock.advanceTimeByFrame()
        composeTestRule.waitForIdle()
        
        composeTestRule.runOnUiThread {
            composeTestRule.runWithoutImplicitWait {
                // This is most effective when querying multiple nodes in a single frame. 
                // It prevents the redundant synchronization overhead that would 
                // otherwise occur on every individual query.
                val box1 = composeTestRule.onNodeWithTag("Box1").fetchSemanticsNode()
                val box2 = composeTestRule.onNodeWithTag("Box2").fetchSemanticsNode()
                
                assertThat(box1.boundsInRoot.right).isAtMost(box2.boundsInRoot.left)
            }
        }
    }
}

Các thay đổi đáng chú ý khác:

  • Giờ đây, API captureToImage cho phép bạn chụp một cửa sổ bật lên hoặc hộp thoại cùng với điểm neo của cửa sổ đó trong một bitmap duy nhất.
  • Đã thêm onRootWithViewInteraction để giới hạn phạm vi tìm kiếm ngữ nghĩa trong Compose cho các Khung hiển thị Android cụ thể. Điều này giúp đơn giản hoá việc kiểm thử giao diện người dùng kết hợp, chẳng hạn như RecyclerViews, mà không cần các thẻ kiểm thử duy nhất trong mã phát hành chính thức.
  • Giờ đây, bạn có thể áp dụng chú thích @PreviewWrapper cho các lớp @MultiPreview tuỳ chỉnh, cho phép thiết lập bản xem trước có thể dùng lại (chẳng hạn như giao diện tuỳ chỉnh) trên nhiều thành phần.

Chúc bạn sáng tác vui vẻ!

Compose 1.12 giúp việc phát triển ứng dụng trở nên dễ dàng và thể hiện rõ ràng hơn bao giờ hết, với các công cụ như chuyển sắc dạng lưới, hỗ trợ gam màu rộng, phông chữ có thể tải xuống, tích hợp Trình quản lý thông tin xác thực và các công cụ kiểm thử nhanh hơn. Như mọi khi, chúng tôi rất coi trọng ý kiến đóng góp của bạn. Vì vậy, vui lòng chia sẻ ý kiến phản hồi về những thay đổi này hoặc những gì bạn muốn thấy tiếp theo trên trình theo dõi vấn đề của chúng tôi. Chúc bạn sáng tác thành công!

Tác giả:
Đọc tiếp