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

Thời gian đọc: 5 phút
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 cho các mô-đun Compose chính (xem toàn bộ bản ánh xạ BOM), giới thiệu các API hình ảnh phong phú như dải màu chuyển sắc dạng lưới và hỗ trợ dải 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ư các điểm cải tiến đáng kể về hiệu suất và thử nghiệm.

Để 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 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à SDK biên dịch: 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òn được dùng nữa: Di chuyển sang Modifier.onVisibilityChanged(), giúp theo dõi ngưỡng hiển thị chính xác hơn.

Đồ hoạ

Màu chuyển sắc dạng lưới

Compose 1.12 ra mắt MeshGradientPainter để giúp bạn tạo độ dốc màu tự nhiên, 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.

Hỗ trợ gam màu rộng và HDR

Màn hình hiện đại mang lại độ trung thực màu sắc cao hơn và dải động cao hơn. Trong Compose 1.12, tính năng hỗ trợ toàn bộ quy trình cho Gam màu rộng (P3) và kết xuất HDR đã được bật trên đồ hoạ, màu và chương trình đổ bóng của Compose. Màu được xác định trong không gian màu sắc không phải sRGB (chẳng hạn như Display P3) được giữ nguyên cho đến khi kết xuất hình ảnh trên nền tảng mà không cần giới hạn giá trị màu. Màu sắc sẽ quay về sRGB một cách an toàn nếu sử dụng không gian màu sắc không được hỗ trợ (ví dụ: CieXyz, CieLab hoặc Oklab), dựa vào không gian màu sắc trên 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 hình ảnh 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 ẩn khi lớp được chuyển lên 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 về Styles API của Compose – một cách thống 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 an toàn về kiểu và tính chính xác có thể dự đoán, cũng như hỗ trợ việc xây dựng hệ thống thiết kế tuỳ chỉnh. 

Để đảm bảo chúng tôi xây dựng lớp nền tảng này một cách chính xác, API này sẽ vẫn ở giai đoạn thử nghiệm và có thể có những thay đổi có thể gây lỗi. 

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

Quá tải SideEffect có khoá

SideEffect hiện hỗ trợ các đối số chính, cho phép bạn kích hoạt 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 coroutine hoặc khối xử lý. SideEffect nhanh hơn tới 90% so với LaunchedEffect và nhanh hơn khoảng 20% so với DisposableEffect. Xin 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 để bắt đầu sau khi khung 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 đổi hai giai đoạn có tính tương tác

  • 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ị, ví dụ: để theo dõi cử chỉ xem trước thao tác quay lại.
  • Điều khiển ả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 ảnh động (như tỷ lệ hoặc độ lệch) hiện có thể được điều khiển theo cách thủ công theo thời gian thực (ví dụ: theo dõi cử chỉ vuốt).
  • Chuyển giao liền mạch: Sau khi giai đoạn trì hoãn kết thúc, công cụ chuyển đổi sẽ tiếp quản và thực hiện quá trình chuyển giao liền mạch, bao gồm cả việc chuyển giao vậ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 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 vùng chứa mẹ trong giai đoạn chuyển đổi bị trì 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à hai 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 giao cho ảnh động được kích hoạt:

colorCards.gif

Tích hợp văn bản, dữ liệu đầu vào và 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 cùng dòng 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ư bên trong textFieldState.edit { ... } hoặc InputTransformation). Ngoài ra, TextFieldBuffer còn cung cấp các API getSpanStyles() và getParagraphStyles() trả về đố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ị thuộc tính chỉ đọc textStyles để truy vấn các kiểu đang hoạt động trên các dải ô, còn 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ú thích tuỳ chỉnh được duy trì trong suốt 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à ghi nhận có lập trình đối với lựa chọn văn bản trong SelectionContainer. Việc nâng đối tượng SelectionState thông qua rememberSelectionState() và truyền vào SelectionContainer sẽ hiển thị selectedTexts dưới dạng danh sách phản ứng của AnnotatedStrings, đồng thời cung cấp các phương thức như selectAll(), clear(), select(TextRange) và extendSelectionByWord().

Ngoài ra, hãy sử 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 phạm vi chung. 

@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

Trường văn bản trong Compose hiện tích hợp sẵ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 (dưới API 34 do androidx.credentials library xử lý). Bằng cách đính kèm thuộc tính ngữ nghĩa credentialRequest mới với CredentialRequestData, dữ liệu đầu vào dạng văn bản có thể nhắc khoá truy cập, thông tin xác thực đã 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ợ 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 văn bản đã chọn ra ngoài khung nhìn trong SelectionContainer.
  • Thêm tính năng hỗ trợ âm thanh tương tác tự động (nhấp và điều hướng tiêu điểm) vào các thành phần Compose, cùng với một 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, trình theo dõi lượt nhấp ngữ nghĩa hiện 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à cơ chế ghi đè tuyệt đối.

Cải tiến bố cục

Khu vực được đặt tên trong bố cục lưới

Giờ đây, bạn có thể dễ dàng tạo bố cục 2D phức tạp bằng các vùng được đặt tên trong thành phần @Experimental Grid. Thay vì quản lý chỉ mục hàng và cột 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à đặt 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, 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 xây dựng các ứ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 nhận thấy Thời gian hiển thị khung hình đầu tiên (thời gian cần thiết để ứng dụng tạo khung hình đầu tiên) tương đương với Khung hiển thị trong điểm chuẩn của chúng tôi.

timetoinitialdisplay@2x _v2.png

Nâng cấp công cụ và kiểm thử

Đồng bộ hoá kiểm thử

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

  • hasPendingWork: Kiểm tra một cách thụ động 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 tăng thời gian, đâ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 tắt tính năng đồng bộ hoá ngầm ẩn 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 cửa sổ bật lên hoặc hộp thoại cùng với neo của cửa sổ bật lên hoặc hộp thoại đó trong một bitmap duy nhất.
  • Thêm onRootWithViewInteraction để đặt 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 thẻ kiểm thử riêng biệt trong mã phát hành công khai.
  • 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ể sử 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 lập trình vui vẻ!

Compose 1.12 giúp việc phát triển ứng dụng trở nên dễ dàng và giàu tính biểu đạt hơn bao giờ hết, nhờ có dải chuyển màu dạng lưới, khả năng hỗ trợ dải màu rộng, phông chữ biến đổi có thể tải xuống, tính nă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ư thường lệ, chúng tôi rất trân 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 điều bạn muốn thấy tiếp theo trên trình theo dõi sự cố của chúng tôi. Chúc bạn luôn thành công!

Tác giả:
Tiếp tục đọc