Hôm nay, bản phát hành Jetpack Compose tháng 4 năm 2026 đã ổn định. Bản phát hành này chứa phiên bản 1.11 của các mô-đun Compose chính (xem toàn bộ Bản ánh xạ BOM), công cụ gỡ lỗi phần tử dùng chung, sự kiện bàn di chuột và nhiều nội dung khác. Chúng tôi cũng có một vài API thử nghiệm mà chúng tôi rất mong bạn dùng thử và đưa ra ý kiến phản hồi.
Để sử dụng 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:
implementation(platform("androidx.compose:compose-bom:2026.04.01"))
Các thay đổi trong Compose 1.11.0
Thực thi coroutine trong kiểm thử
Chúng tôi sẽ ra mắt một bản cập nhật quan trọng về cách Compose xử lý thời gian kiểm thử. Sau giai đoạn chọn sử dụng được công bố trong Compose 1.10, các API kiểm thử phiên bản 2 hiện là API mặc định và các API phiên bản 1 không còn được dùng nữa. Thay đổi quan trọng là sự thay đổi trong trình điều phối kiểm thử mặc định. Trong khi các API phiên bản 1 dựa vào UnconfinedTestDispatcher (thực thi coroutine ngay lập tức), thì các API phiên bản 2 sử dụng StandardTestDispatcher. Điều này có nghĩa là khi một coroutine được khởi chạy trong các hoạt động kiểm thử, coroutine đó hiện đã được đưa vào hàng đợi và không thực thi cho đến khi đồng hồ ảo được đẩy nhanh.
Điều này mô phỏng tốt hơn các điều kiện thực tế, loại bỏ hiệu quả các tình huống tương tranh và giúp bộ kiểm thử của bạn mạnh mẽ hơn đáng kể và ít bị lỗi hơn.
Để đảm bảo các kiểm thử của bạn phù hợp với hành vi coroutine tiêu chuẩn và tránh các vấn đề về khả năng tương thích trong tương lai, bạn nên di chuyển bộ kiểm thử của mình. Hãy xem hướng dẫn di chuyển toàn diện của chúng tôi để biết thông tin về mối liên kết API và các cách khắc phục phổ biến.
Cải tiến thành phần dùng chung và công cụ ảnh động
Chúng tôi cũng đã thêm một số công cụ gỡ lỗi trực quan hữu ích cho các phần tử dùng chung và Modifier.animatedBounds. Giờ đây, bạn có thể xem chính xác những gì đang diễn ra trong hệ thống, chẳng hạn như ranh giới mục tiêu, quỹ đạo ảnh động và số lượng kết quả trùng khớp được tìm thấy. Nhờ đó, bạn có thể dễ dàng phát hiện lý do khiến quá trình chuyển đổi có thể không hoạt động như mong đợi. Để sử dụng công cụ mới, bạn chỉ cần bao quanh SharedTransitionLayout bằng composable LookaheadAnimationVisualDebugging.
LookaheadAnimationVisualDebugging( overlayColor = Color(0x4AE91E63), isEnabled = true, multipleMatchesColor = Color.Green, isShowKeylabelEnabled = false, unmatchedElementColor = Color.Red, ) { SharedTransitionLayout { CompositionLocalProvider( LocalSharedTransitionScope provides this, ) { // your content } } }
Sự kiện trên bàn di chuột
Chúng tôi đã cải tiến tính năng hỗ trợ của Compose cho bàn di chuột, chẳng hạn như bàn di chuột tích hợp trên máy tính xách tay, bàn di chuột có thể gắn vào máy tính bảng hoặc bàn di chuột bên ngoài/bàn di chuột ảo. Giờ đây, các sự kiện cơ bản trên bàn di chuột thường sẽ được coi là sự kiện PointerType.Mouse, giúp hành vi của chuột và bàn di chuột phù hợp hơn với kỳ vọng của người dùng. Trước đây, các sự kiện bàn di chuột này được hiểu là thao tác chạm giả trên màn hình cảm ứng của PointerType.Touch, dẫn đến trải nghiệm người dùng khó hiểu. Ví dụ: thao tác nhấp và kéo bằng bàn di chuột sẽ cuộn thay vì chọn. Bằng cách thay đổi loại con trỏ mà các sự kiện này có trong bản phát hành mới nhất của Compose, thao tác nhấp và kéo bằng bàn di chuột sẽ không còn cuộn nữa.
Chúng tôi cũng bổ sung tính năng hỗ trợ cho các cử chỉ phức tạp hơn trên bàn di chuột mà nền tảng nhận dạng được kể từ API 34, bao gồm cả thao tác vuốt bằng hai ngón tay và thao tác chụm. Các thành phần như Modifier.scrollable và Modifier.transformable sẽ tự động nhận dạng những cử chỉ này để có hành vi phù hợp hơn với bàn di chuột.
Những thay đổi này cải thiện hành vi của bàn di chuột trên các thành phần tích hợp sẵn, loại bỏ độ dốc cảm ứng thừa, cử chỉ bắt đầu kéo và thả trực quan hơn, lựa chọn nhấp đúp và nhấp ba lần trong trường văn bản, cũng như trình đơn theo bối cảnh kiểu máy tính trong trường văn bản.
Để kiểm thử hành vi của bàn di chuột, có các API kiểm thử mới với performTrackpadInput, cho phép xác thực hành vi của ứng dụng khi dùng với bàn di chuột. Nếu bạn có trình phát hiện cử chỉ tuỳ chỉnh, hãy xác thực hành vi trên các loại phương thức nhập, bao gồm màn hình cảm ứng, chuột, bàn di chuột và bút cảm ứng, đồng thời đảm bảo hỗ trợ con lăn chuột và cử chỉ trên bàn di chuột.
Giá trị mặc định của máy chủ lưu trữ thành phần kết hợp (Thời gian chạy Compose)
Chúng tôi đã ra mắt HostDefaultProvider, LocalHostDefaultProvider, HostDefaultKey và ViewTreeHostDefaultKey để cung cấp các dịch vụ cấp máy chủ trực tiếp thông qua compose-runtime. Điều này giúp các thư viện không cần phụ thuộc vào compose-ui để tra cứu, nhờ đó hỗ trợ Kotlin Multiplatform tốt hơn. Để liên kết các giá trị này với cây thành phần, tác giả thư viện có thể sử dụng compositionLocalWithHostDefaultOf để tạo CompositionLocal phân giải các giá trị mặc định từ máy chủ lưu trữ.
Trình bao bọc bản xem trước
Bản xem trước tuỳ chỉnh của Android Studio là một tính năng mới cho phép bạn xác định chính xác cách hiển thị nội dung của bản xem trước trong Compose.
Bằng cách triển khai giao diện PreviewWrapperProvider và áp dụng chú thích @PreviewWrapper mới, bạn có thể dễ dàng chèn logic tuỳ chỉnh, chẳng hạn như áp dụng một Theme cụ thể. Bạn có thể áp dụng chú thích này cho một hàm được chú thích bằng @Composable và @Preview hoặc @MultiPreview, mang đến một giải pháp chung, dễ sử dụng, hoạt động trên các tính năng đang ở giai đoạn xem trước và giảm đáng kể mã lặp lại.
class ThemeWrapper: PreviewWrapperProvider { @Composable override fun Wrap(content: @Composable (() -> Unit)) { JetsnackTheme { content() } } } @PreviewWrapper(ThemeWrapper::class) @Preview @Composable private fun ButtonPreview() { // JetsnackTheme in effect Button(onClick = {}) { Text(text = "Demo") } }
Ngừng sử dụng và xoá
- Như đã thông báo trong bài đăng trên blog về Compose 1.10, chúng tôi sẽ ngừng sử dụng
Modifier.onFirstVisible(). Tên của hàm này thường gây hiểu lầm, đặc biệt là trong bố cục tải từng phần, nơi hàm này sẽ kích hoạt nhiều lần trong khi cuộn. Bạn nên di chuyển sangModifier.onVisibilityChanged()để theo dõi chính xác hơn trạng thái hiển thị theo cách thủ công, phù hợp với các yêu cầu cụ thể của trường hợp sử dụng. - Cờ
ComposeFoundationFlags.isTextFieldDpadNavigationEnabledđã bị xoá vì tính năng điều hướng bằng D-pad choTextFieldshiện luôn được bật theo mặc định. Hành vi mới đảm bảo rằng các sự kiện của d-pad từ tay điều khiển trò chơi hoặc điều khiển TV trước tiên sẽ di chuyển con trỏ theo hướng đã cho. Tiêu điểm chỉ có thể di chuyển đến một phần tử khác khi con trỏ đến cuối văn bản.
API sắp ra mắt
Trong bản phát hành Compose 1.12.0 sắp tới, compileSdk sẽ được nâng cấp lên compileSdk 37, cùng với AGP 9 và tất cả ứng dụng cũng như thư viện phụ thuộc vào Compose sẽ kế thừa yêu cầu này. Bạn nên cập nhật các phiên bản mới nhất vì Compose hướng đến việc nhanh chóng áp dụng compileSdks mới để cung cấp quyền truy cập vào các tính năng mới nhất của Android. Hãy nhớ xem tài liệu tại đây để biết thêm thông tin về phiên bản AGP được hỗ trợ cho các cấp độ API khác nhau.
Trong Compose 1.11.0, các API sau đây được giới thiệu dưới dạng @Experimental và chúng tôi rất mong nhận được ý kiến phản hồi của bạn khi bạn khám phá các API này trong ứng dụng của mình. Xin lưu ý rằng @Experimental APIs được cung cấp để đánh giá và phản hồi sớm, đồng thời có thể trải qua những thay đổi đáng kể hoặc bị xoá trong các bản phát hành sau này.
Kiểu (Thử nghiệm)
Chúng tôi sẽ ra mắt một API nền tảng thử nghiệm mới để tạo kiểu. Style API là một mô hình mới để tuỳ chỉnh các thành phần hình ảnh của thành phần, vốn thường được thực hiện bằng đối tượng sửa đổi. Thành phần này được thiết kế để giúp bạn tuỳ chỉnh sâu hơn và dễ dàng hơn bằng cách hiển thị một bộ tiêu chuẩn thuộc tính có thể tạo kiểu, với kiểu đơn giản dựa trên trạng thái và hiệu ứng chuyển đổi ảnh động. Với API mới này, chúng tôi đã nhận thấy những lợi ích đầy hứa hẹn về hiệu suất. Chúng tôi dự định áp dụng Kiểu trong các thành phần Material sau khi Style API ổn định.
Ví dụ cơ bản về cách ghi đè nền kiểu trạng thái được nhấn:
@Composable fun LoginButton(modifier: Modifier = Modifier) { Button( onClick = { // Login logic }, modifier = modifier, style = { background( Brush.linearGradient( listOf(lightPurple, lightBlue) ) ) width(75.dp) height(50.dp) textAlign(TextAlign.Center) externalPadding(16.dp) pressed { background( Brush.linearGradient( listOf(Color.Magenta, Color.Red) ) ) } } ){ Text( text = "Login", ) } }
Hãy xem tài liệu và báo cáo lỗi tại đây.
MediaQuery (Thử nghiệm)
API mediaQuery mới cung cấp một cách khai báo và hiệu quả để điều chỉnh giao diện người dùng cho phù hợp với môi trường. Hàm này tóm tắt quy trình truy xuất thông tin phức tạp thành các điều kiện đơn giản trong một UiMediaScope, đảm bảo quá trình kết hợp lại chỉ diễn ra khi cần thiết.
Nhờ hỗ trợ nhiều tín hiệu môi trường (từ các chức năng của thiết bị như loại bàn phím và độ chính xác của con trỏ, cho đến các trạng thái theo bối cảnh như kích thước và tư thế cửa sổ), bạn có thể xây dựng trải nghiệm thích ứng sâu sắc. Hiệu suất được tích hợp sẵn với derivedMediaQuery để xử lý các bản cập nhật tần suất cao, trong khi khả năng ghi đè phạm vi giúp việc thử nghiệm và xem trước diễn ra liền mạch trên các cấu hình phần cứng. Trước đây, để có quyền truy cập vào một số thuộc tính của thiết bị (chẳng hạn như thiết bị có đang ở chế độ mặt bàn hay không), bạn cần viết nhiều mã nguyên mẫu:
@Composable fun isTabletopPosture( context: Context = LocalContext.current ): Boolean { val windowLayoutInfo by WindowInfoTracker .getOrCreate(context) .windowLayoutInfo(context) .collectAsStateWithLifecycle(null) return windowLayoutInfo.displayFeatures.any { displayFeature -> displayFeature is FoldingFeature && displayFeature.state == FoldingFeature.State.HALF_OPENED && displayFeature.orientation == FoldingFeature.Orientation.HORIZONTAL } } @Composable fun VideoPlayer() { if(isTabletopPosture()) { TabletopLayout() } else { FlatLayout() } }
Giờ đây, với UIMediaQuery, bạn có thể thêm cú pháp mediaQuery để truy vấn các thuộc tính của thiết bị, chẳng hạn như liệu thiết bị có đang ở chế độ mặt bàn hay không:
@OptIn(ExperimentalMediaQueryApi::class) @Composable fun VideoPlayer() { if (mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop }) { TabletopLayout() } else { FlatLayout() } }
Hãy xem tài liệu và báo cáo lỗi tại đây.
Lưới (Thử nghiệm)
Grid là một API mới mạnh mẽ để xây dựng bố cục hai chiều phức tạp trong Jetpack Compose. Mặc dù Row và Column rất phù hợp với các thiết kế tuyến tính, nhưng Grid cung cấp cho bạn quyền kiểm soát cấu trúc cần thiết cho cấu trúc cấp màn hình và các thành phần phức tạp mà không cần đến danh sách có thể cuộn. Grid cho phép bạn xác định bố cục bằng cách sử dụng các dải, khoảng trống và ô, đồng thời cung cấp các tuỳ chọn định cỡ quen thuộc như Dp, tỷ lệ phần trăm, kích thước nội dung nội tại và đơn vị "Fr" linh hoạt.
@OptIn(ExperimentalGridApi::class) @Composable fun GridExample() { Grid( config = { repeat(4) { column(0.25f) } repeat(2) { row(0.5f) } gap(16.dp) } ) { Card1(modifier = Modifier.gridItem(rowSpan = 2) Card2(modifier = Modifier.gridItem(colmnSpan = 3) Card3(modifier = Modifier.gridItem(columnSpan = 2) Card4() } }
Bạn có thể đặt các mục tự động hoặc kéo dài chúng một cách rõ ràng trên nhiều hàng và cột để đảm bảo độ chính xác. Điều tuyệt vời nhất là thành phần này có khả năng thích ứng cao – bạn có thể linh động định cấu hình lại các dải và khoảng cách lưới để thích ứng với các trạng thái của thiết bị, chẳng hạn như chế độ mặt bàn hoặc thay đổi hướng, đảm bảo giao diện người dùng của bạn trông đẹp mắt trên mọi kiểu dáng.
Hãy xem tài liệu và báo cáo lỗi tại đây.
FlexBox (Thử nghiệm)
FlexBox là một vùng chứa bố cục được thiết kế cho giao diện người dùng thích ứng, hiệu suất cao. Thành phần này quản lý kích thước mục và phân bổ không gian dựa trên kích thước vùng chứa có sẵn. Mô hình này xử lý các tác vụ phức tạp như gói (wrap) và căn chỉnh nhiều trục của các mục (justifyContent, alignItems, alignContent). Mô hình này cho phép các mục tăng (grow) hoặc thu nhỏ (shrink) để lấp đầy vùng chứa.
@OptIn(ExperimentalFlexBoxApi::class) fun FlexBoxWrapping(){ FlexBox( config = { wrap(FlexWrap.Wrap) gap(8.dp) } ) { RedRoundedBox() BlueRoundedBox() GreenRoundedBox(modifier = Modifier.width(350.dp).flex { grow(1.0f) }) OrangeRoundedBox(modifier = Modifier.width(200.dp).flex { grow(0.7f) }) PinkRoundedBox(modifier = Modifier.width(200.dp).flex { grow(0.3f) }) } }
Hãy xem tài liệu và báo cáo lỗi tại đây.
Triển khai SlotTable mới (Thử nghiệm)
Chúng tôi đã ra mắt một cách triển khai mới cho SlotTable, được tắt theo mặc định trong bản phát hành này. SlotTable là cấu trúc dữ liệu nội bộ mà thời gian chạy Compose sử dụng để theo dõi trạng thái của hệ phân cấp thành phần, theo dõi các trường hợp không hợp lệ/tái cấu trúc, lưu trữ các giá trị đã ghi nhớ và theo dõi tất cả siêu dữ liệu của thành phần trong thời gian chạy. Cách triển khai mới này được thiết kế để cải thiện hiệu suất, chủ yếu là về các nội dung chỉnh sửa ngẫu nhiên.
Để dùng thử SlotTable mới, hãy bật ComposeRuntimeFlags.isLinkBufferComposerEnabled.
Bắt đầu lập trình ngay hôm nay!
Với rất nhiều API mới thú vị trong Jetpack Compose và nhiều API khác sắp ra mắt, đây là thời điểm tốt nhất để di chuyển sang Jetpack Compose. Như thường lệ, chúng tôi rất trân trọng ý kiến phản hồi và yêu cầu về tính năng của bạn (đặc biệt là về các tính năng @Experimental vẫn đang trong quá trình phát triển) — vui lòng gửi ý kiến phản hồi và yêu cầu tại đây. Chúc bạn luôn thành công!
-
Tin tức về sản phẩmKhi quá trình phát triển tác nhân AI tăng tốc, kỹ thuật Android đang đạt đến một ranh giới mới thú vị: chuyển từ tính năng hoàn thành mã hỗ trợ sang các tác nhân thực thi từ đầu đến cuối theo hướng dẫn của bạn. Bạn có toàn quyền lựa chọn và linh hoạt sử dụng các mô hình và tác nhân.
Jason Buchel • Đọc trong 3 phút -
Tin tức về sản phẩmHôm nay, chúng tôi đã chia sẻ về cách chúng tôi đưa tầm nhìn "không chỉ là một cửa hàng" sang một chương mới. Từ thẻ Bạn (hiện là trang chủ cá nhân của hơn 250 triệu số người dùng hoạt động hằng tháng) cho đến nền tảng trò chơi hợp nhất kết nối hơn 700 triệu hồ sơ người chơi, Google Play luôn đáp ứng nhu cầu của người dùng mọi lúc mọi nơi.
Paul Feng • Đọc trong 3 phút -
Tin tức về sản phẩmChúng tôi rất vui được giúp người dùng thể hiện bản thân và sử dụng những công cụ này thông qua Googlebook.
Cyrus Stoller • Thời gian đọc: 2 phút
Nhận thông tin chi tiết mới nhất về hoạt động phát triển Android trong hộp thư đến của bạn hằng tuần.