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 cốt lõi (xem BOM mapping đầy đủ), các công cụ gỡ lỗi thành phần 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à bạn nên dùng thử và gửi ý kiến phản hồi cho chúng tôi.
Để sử dụng bản phát hành hôm nay, hãy nâng cấp phiên bản Compose BOM 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 các bài kiểm thử
Chúng tôi sẽ giới thiệu một bản cập nhật lớn về cách Compose xử lý thời gian kiểm thử. Sau thời gian chọn tham gia được công bố trong Compose 1.10, các API kiểm thử v2 hiện là mặc định và các API v1 đã ngừng hoạt động. Thay đổi chính là sự chuyển đổi trong trình điều phối kiểm thử mặc định. Trong khi các API v1 dựa vào UnconfinedTestDispatcher (thực thi coroutine ngay lập tức), thì các API v2 sử dụng StandardTestDispatcher. Điều này có nghĩa là khi một coroutine được chạy trong các bài kiểm thử, coroutine đó sẽ được xếp 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 sản xuất, loại bỏ hiệu quả các điều kiện xung đột 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 bài 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ử. Hãy xem hướng dẫn di chuyển toàn diện của chúng tôi để biết các bản đồ API và bản sửa lỗi thường gặp.
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 thành phần dùng chung và Modifier.animatedBounds. Giờ đây, bạn có thể thấy chính xác những gì đang diễn ra bên dưới (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), giúp bạn 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 thành phần kết hợp 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 bàn di chuột
Chúng tôi đã cải tiến tính năng hỗ trợ 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 cho máy tính bảng hoặc bàn di chuột ảo/bên ngoài. Các sự kiện cơ bản trên bàn di chuột hiện sẽ thường được coi là sự kiện PointerType.Mouse, giúp điều chỉnh hành vi của chuột và bàn di chuột cho phù hợp hơn với kỳ vọng của người dùng. Trước đây, các sự kiện trên bàn di chuột này được diễn giải là ngón tay 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ụ: việ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, việ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 đã thêm tính năng hỗ trợ cho các cử chỉ phức tạp hơn trên bàn di chuột như được nền tảng nhận dạng kể từ API 34, bao gồm thao tác vuốt bằng hai ngón tay và thao tác chụm. Các cử chỉ này được các thành phần như Modifier.scrollable và Modifier.transformable tự động nhận dạng để có hành vi tốt hơn với bàn di chuột.
Những thay đổi này cải thiện hành vi cho bàn di chuột trên các thành phần tích hợp, loại bỏ độ dốc cảm ứng dư thừa, cử chỉ bắt đầu kéo và thả trực quan hơn, thao tác chọn bằng cách nhấp đúp và nhấp ba lần trong các trường văn bản, cũng như trình đơn theo bối cảnh theo kiểu máy tính trong các 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 được sử 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 đầu vào, 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ợ bánh xe cuộ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 (thời gian chạy Compose)
Chúng tôi đã giới thiệu HostDefaultProvider, LocalHostDefaultProvider, HostDefaultKey, và ViewTreeHostDefaultKey để cung cấp các dịch vụ ở cấp máy chủ lưu trữ trực tiếp thông qua compose-runtime. Điều này giúp loại bỏ nhu cầu thư viện phụ thuộc vào compose-ui để tra cứu, hỗ trợ tốt hơn cho Kotlin Multiplatform. Để 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 trong 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 nội dung của bản xem trước trong Compose được hiển thị.
Bằng cách triển khai giao diện PreviewWrapperProvider và áp dụng chú giải @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ể. Chú giải này có thể được áp dụng cho một hàm được chú giải bằng @Composable và @Preview hoặc @MultiPreview, cung cấp một giải pháp chung, dễ sử dụng, hoạt động trên các tính năng 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 dẫn đến những hiểu lầm, đặc biệt là trong các bố cục trì hoãn, nơi hàm này sẽ kích hoạt nhiều lần trong quá trình cuộn. Bạn nên di chuyển sangModifier.onVisibilityChanged(), cho phép theo dõi thủ công chính xác hơn các trạng thái hiển thị 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 D-pad từ gamepad hoặc điều khiển từ xa của TV sẽ di chuyển con trỏ theo hướng đã cho. Tiêu điểm chỉ có thể di chuyển sang một phần tử khác khi con trỏ đạt đế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, với AGP 9 và tất cả các ứng dụng cũng như thư viện phụ thuộc vào Compose đều 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 phát hành, 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 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ể thay đổi hoặc bị xoá đáng kể trong các bản phát hành sau này.
Kiểu (Thử nghiệm)
Chúng tôi sẽ giới thiệu một API nền tảng thử nghiệm mới cho kiểu. Style API là một mô hình mới để tuỳ chỉnh các phần tử trực quan của thành phần, thường được thực hiện bằng các công cụ sửa đổi. API này được thiết kế để mở ra khả năng tuỳ chỉnh sâu hơn, dễ dàng hơn bằng cách hiển thị một tập hợp các thuộc tính có thể tạo kiểu tiêu chuẩn với kiểu dựa trên trạng thái đơn giản và các quá trình chuyển đổi ảnh động. Với API mới này, chúng tôi đã thấy lợi ích 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ề việc ghi đè nền kiểu trạng thái đã 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 mọi lỗi tại đây.
MediaQuery (Thử nghiệm)
API mediaQuery mới cung cấp một cách thức 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. API này trừu tượng hoá việc truy xuất thông tin phức tạp thành các điều kiện đơn giản trong UiMediaScope, đảm bảo chỉ tái tạo thành phần khi cần.
Với khả năng hỗ trợ nhiều tín hiệu môi trường (từ các tính năng của thiết bị như loại bàn phím và độ chính xác của con trỏ, đến các trạng thái theo bối cảnh như kích thước và tư thế của cửa sổ), bạn có thể xây dựng trải nghiệm có khả năng phản hồi sâu. 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 số cao, trong khi khả năng ghi đè phạm vi giúp việc kiểm thử và xem trước trở nên liền mạch trên các cấu hình phần cứng. Trước đây, để truy cập vào một số thuộc tính của thiết bị (chẳng hạn như nếu thiết bị ở chế độ để bàn), bạn cần viết nhiều mã soạn sẵn để thực hiện việc này:
@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ư nếu thiết bị ở chế độ để bàn:
@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 mọi lỗi tại đây.
Lưới (Thử nghiệm)
Grid là một API mới mạnh mẽ để xây dựng các 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 kiến 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 đường dẫn, khoảng cách và ô, cung cấp các lựa chọn kích thước quen thuộc như Dp, tỷ lệ phần trăm, kích thước nội dung vốn có và các đơ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ự động đặt các mục hoặc trải rộng các mục một cách rõ ràng trên nhiều hàng và cột để có độ chính xác. Quan trọng nhất là API này có khả năng thích ứng cao – bạn có thể định cấu hình lại các đường dẫn và khoảng cách của lưới một cách linh hoạt để phản hồi các trạng thái của thiết bị như chế độ để 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 các hệ số hình dạng.
Hãy xem tài liệu và báo cáo mọi 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 có hiệu suất cao và khả năng thích ứng. API này quản lý việc định kích thước mục và phân phối không gian dựa trên kích thước vùng chứa có sẵn.API 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). API 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 mọi lỗi tại đây.
Triển khai SlotTable mới (Thử nghiệm)
Chúng tôi đã giới thiệu một cách triển khai mới của SlotTable, bị 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 lượt vô hiệu hoá/tái tạo thành phần, 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à xung quanh các 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 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 báo cáo tại đây. Chúc bạn luôn thành công!
-
Tin tức về sản phẩmVào tháng 3, chúng tôi đã giới thiệu Android Bench – bảng xếp hạng LLM của chúng tôi cho các tác vụ phát triển Android trong thế giới thực. Kể từ đó, chúng tôi đã cải tiến điểm chuẩn dựa trên ý kiến phản hồi của bạn, bao gồm cả việc đánh giá các mô hình trọng số mở và thêm các phương diện chi phí và hiệu quả vào bảng xếp hạng.
Zoe Lopez-Latorre • 3 phút đọc -
Tin tức về sản phẩmTại Google Play, chúng tôi cam kết mang đến trải nghiệm tốt nhất có thể cho người dùng, đồng thời đảm bảo nhà phát triển có các công cụ và khả năng thích ứng để thành công.
Paul Feng • 3 phút đọc -
Tin tức về sản phẩmNăm ngoái, chúng tôi đã giới thiệu quy trình xác minh nhà phát triển Android để tăng cường tính bảo mật của hệ sinh thái và ngăn chặn các đối tượng xấu ẩn danh để phát hành ứng dụng gây hại.
Matthew Forsythe • 2 phút đọc
Nhận thông tin chi tiết mới nhất về quá trình phát triển Android được gửi vào hộp thư đến của bạn mỗi tuần.