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

Có gì 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 cho các mô-đun Compose cốt lõi (xem bản đồ BOM đầy đủ ), giới thiệu các API trực quan phong phú như Mesh Gradients và hỗ trợ Wide Color Gamut (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ững cải tiến đáng kể về thử nghiệm và hiệu năng.

Để cập nhật dự án của bạn lên phiên bản mới nhất, hãy nâng cấp phiên bản Compose BOM của bạn lên 2026.08.00:

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

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

  • AGP & Compile SDK: Compose 1.12 cập nhật compileSdk lên API 37, yêu cầu AGP tối thiểu 9.1.2. Xin nhắc lại, Compose sẽ luôn nhắm đến phiên bản compileSdk mới nhất. Tìm hiểu thêm về thay đổi này tại đây.
  • Modifier.onFirstVisible() đã lỗi thời Di chuyển đếnModifier.onVisibilityChanged() Điều này giúp theo dõi ngưỡng khả năng hiển thị chính xác hơn.

Đồ hoạ

Lưới chuyển sắc

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 có độ trung thực về màu sắc cao hơn và dải tương phản động rộng 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)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 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 các 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 một 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 an toàn về kiểu nghiêm ngặt và độ chính xác có thể dự đoán được, đồ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ể mang lại hiệu suất tốt hơn so với việc sử dụng LaunchedEffect hoặc DisposableEffect khi bạn không cần khối coroutine 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ớiDeferredAnimatedContent 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.
  • Điều khiển ảnh động theo cách thủ công: Trong giai đoạn hoãn lại 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 bị 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 độ) cho 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ẹ của chúng trong giai đoạn chuyển đổi bị hoãn lại 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 đị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 SpanStyleParagraphStyle 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()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à quan sát theo phương thức lập trình đối với lựa chọn văn bản trong một 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)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 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 (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 bằng 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 (nhấp và điều hướ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 sự thay đổi này, giờ đây, 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 DateTimeDateTime 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 Lưới @Experimental. Thay vì quản lý chỉ mục cột và hàng bằ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

Cũng 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 năng của Compose để đảm bảo rằng framework 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 đ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ụ

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

Compose 1.12 giới thiệu 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 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 tăng thời gian, rất phù hợp với 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 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 hóa việc kiểm thử giao diện người dùng lai, chẳng hạn như RecyclerViews, mà không cần yêu cầu các thẻ kiểm thử riêng biệt trong mã sản xuất.
  • 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 chuyển màu 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ẻ phản hồi của bạn 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 sự cố của chúng tôi. Chúc bạn sáng tác vui vẻ!

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