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 12 năm 2025

Đọc trong 6 phút
Nick Butcher
Giám đốc sản phẩm

Hôm nay, bản phát hành Jetpack Compose tháng 12 năm 2025 đã ổn định. Bản phát hành này chứa phiên bản 1.10 của các mô-đun Compose cốt lõi và phiên bản 1.4 của Material 3 (xem toàn bộ sơ đồ BOM), bổ sung các tính năng mới và cải thiện đáng kể hiệu suất.

Để 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 2025.12.00:

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

Cải thiện hiệu suất

Chúng tôi biết rằng hiệu suất thời gian chạy của ứng dụng là vô cùng quan trọng đối với bạn và người dùng của bạn, vì vậy, hiệu suất là ưu tiên hàng đầu của nhóm Compose. Bản phát hành này mang đến một số điểm cải thiện – và bạn sẽ nhận được tất cả những điểm cải thiện đó chỉ bằng cách nâng cấp lên phiên bản mới nhất. Các tiêu chí so sánh hiệu suất cuộn nội bộ của chúng tôi cho thấy rằng Compose hiện phù hợp với hiệu suất mà bạn sẽ thấy nếu sử dụng Chế độ xem:

janky.png

Tiêu chí so sánh hiệu suất cuộn so sánh Chế độ xem và Jetpack Compose trên các phiên bản Compose khác nhau

Thành phần có thể tạm dừng trong quá trình tìm nạp trước từng phần

Thành phần có thể tạm dừng trong quá trình tìm nạp trước từng phần hiện được bật theo mặc định. Đây là một thay đổi cơ bản đối với cách hoạt động của lịch biểu thời gian chạy Compose, được thiết kế để giảm đáng kể hiện tượng giật trong khối lượng công việc lớn của giao diện người dùng.

Trước đây, sau khi bắt đầu, thành phần phải chạy cho đến khi hoàn tất. Nếu thành phần phức tạp, điều này có thể chặn luồng chính lâu hơn một khung hình, khiến giao diện người dùng bị đóng băng. Với thành phần có thể tạm dừng, thời gian chạy hiện có thể "tạm dừng" công việc nếu hết thời gian và tiếp tục công việc trong khung hình tiếp theo. Điều này đặc biệt hiệu quả khi được sử dụng với tính năng tìm nạp trước bố cục từng phần để chuẩn bị khung hình trước. Các API CacheWindow bố cục từng phần được giới thiệu trong Compose 1.9 là một cách tuyệt vời để tìm nạp trước nhiều nội dung hơn và hưởng lợi từ thành phần có thể tạm dừng để tạo ra hiệu suất giao diện người dùng mượt mà hơn nhiều.

pausable.gif

Thành phần có thể tạm dừng kết hợp với tính năng tìm nạp trước từng phần giúp giảm hiện tượng giật

Chúng tôi cũng đã tối ưu hoá hiệu suất ở những nơi khác, với các điểm cải thiện đối với Modifier.onPlaced, Modifier.onVisibilityChanged và các cách triển khai công cụ sửa đổi khác. Chúng tôi sẽ tiếp tục đầu tư để cải thiện hiệu suất của Compose.

Tính năng mới

Giữ lại

Compose cung cấp một số API để giữ và quản lý trạng thái trên các vòng đời khác nhau; ví dụ: remember duy trì trạng thái trên các thành phần và rememberSavable/rememberSerializable để duy trì trên hoạt động hoặc quá trình tạo lại.retain là một API mới nằm giữa các API này, cho phép bạn duy trì các giá trị trên các thay đổi về cấu hình mà không cần được chuyển đổi tuần tự, nhưng không phải trên quá trình bị buộc tắt. Vì retain không chuyển đổi tuần tự trạng thái của bạn, nên bạn có thể duy trì các đối tượng như biểu thức lambda, luồng và các đối tượng lớn như bitmap, không thể dễ dàng chuyển đổi tuần tự. Ví dụ: bạn có thể sử dụng retain để quản lý trình phát đa phương tiện (chẳng hạn như ExoPlayer) nhằm đảm bảo rằng quá trình phát nội dung đa phương tiện không bị gián đoạn do thay đổi về cấu hình.

@Composable

fun MediaPlayer() {

    val applicationContext = LocalContext.current.applicationContext

    val exoPlayer = retain { ExoPlayer.Builder(applicationContext).apply { ... }.build() }

    ...

}

Chúng tôi muốn gửi lời cảm ơn đến cộng đồng AndroidDev (đặc biệt là nhóm Circuit), những người đã ảnh hưởng và đóng góp vào thiết kế của tính năng này.

Material 1.4

Phiên bản 1.4.0 của thư viện material3 bổ sung một số thành phần và điểm cải tiến mới:

  • TextField hiện cung cấp phiên bản thử nghiệm dựa trên TextFieldState, cung cấp một phương thức mạnh mẽ hơn để quản lý trạng thái của văn bản. Ngoài ra, các biến thể SecureTextFieldOutlinedSecureTextField mới hiện đã được cung cấp. Thành phần kết hợp Text của material hiện hỗ trợ hành vi autoSize.
  • Thành phần băng chuyền hiện cung cấp một biến thể HorizontalCenteredHeroCarousel mới.
  • TimePicker hiện hỗ trợ chuyển đổi giữa bộ chọn và chế độ nhập.
  • Tay kéo dọc giúp người dùng thay đổi kích thước và/hoặc vị trí của ngăn thích ứng.
centered-hero-carousel.webp

Băng chuyền ngang ở giữa

Xin lưu ý rằng API Biểu cảm của Material 3 tiếp tục được phát triển trong các bản phát hành alpha của thư viện material3. Để tìm hiểu thêm, hãy xem bài nói chuyện gần đây này:

Tính năng ảnh động mới

Chúng tôi tiếp tục mở rộng các API ảnh động, bao gồm cả các bản cập nhật để tuỳ chỉnh ảnh động của phần tử dùng chung.

Phần tử dùng chung động

Theo mặc định, ảnh động sharedElement()sharedBounds() cố gắng tạo ảnh động

thay đổi bố cục bất cứ khi nào tìm thấy khoá phù hợp trong trạng thái mục tiêu. Tuy nhiên, bạn có thể muốn tắt ảnh động này một cách linh hoạt dựa trên một số điều kiện, chẳng hạn như hướng điều hướng hoặc trạng thái giao diện người dùng hiện tại.

Để kiểm soát việc chuyển đổi phần tử dùng chung có xảy ra hay không, giờ đây, bạn có thể tuỳ chỉnh SharedContentConfig được truyền đến rememberSharedContentState(). Thuộc tính isEnabled xác định xem phần tử dùng chung có hoạt động hay không.

SharedTransitionLayout {

        val transition = updateTransition(currentState)

        transition.AnimatedContent { targetState ->

            // Create the configuration that depends on state changing.

            fun animationConfig() : SharedTransitionScope.SharedContentConfig {

                return object : SharedTransitionScope.SharedContentConfig {

                    override val SharedTransitionScope.SharedContentState.isEnabled: Boolean

                        get() =

                            // determine whether to perform a shared element transition

                }

            }

}

Xem tài liệu để biết thêm.

Modifier.skipToLookaheadPosition()

Một công cụ sửa đổi mới, Modifier.skipToLookaheadPosition(), đã được thêm vào trong bản phát hành này, giúp giữ vị trí cuối cùng của một thành phần kết hợp khi thực hiện ảnh động của phần tử dùng chung. Điều này cho phép thực hiện các lượt chuyển đổi như ảnh động kiểu "hiển thị", như bạn có thể thấy trong mẫu Androidify với tính năng hiển thị dần dần của máy ảnh. Xem mẹo về video tại đây để biết thêm thông tin: 

Vận tốc ban đầu trong quá trình chuyển đổi phần tử dùng chung

Bản phát hành này bổ sung một API chuyển đổi phần tử dùng chung mới, prepareTransitionWithInitialVelocity, cho phép bạn truyền vận tốc ban đầu (ví dụ: từ một cử chỉ) đến quá trình chuyển đổi phần tử dùng chung:

Modifier.fillMaxSize()

    .draggable2D(

        rememberDraggable2DState { offset += it },

        onDragStopped = { velocity ->

            // Set up the initial velocity for the upcoming shared element

            // transition.

            sharedContentStateForDraggableCat

                ?.prepareTransitionWithInitialVelocity(velocity)

            showDetails = false

        },

    )
fling-shared.gif

Quá trình chuyển đổi phần tử dùng chung bắt đầu với vận tốc ban đầu từ một cử chỉ

Quá trình chuyển đổi được che phủ

EnterTransition và ExitTransition xác định cách thành phần kết hợp AnimatedVisibility/AnimatedContent xuất hiện hoặc biến mất. Một tuỳ chọn che phủ thử nghiệm mới cho phép bạn chỉ định màu để che phủ hoặc che nội dung; ví dụ: làm mờ dần lớp màu đen bán trong suốt trên nội dung:

veil_2.gif

Nội dung động được che phủ – lưu ý lớp che phủ (hoặc lớp che) bán trong suốt trên nội dung lưới trong quá trình tạo ảnh động

AnimatedContent(

    targetState = page,

    modifier = Modifier.fillMaxSize().weight(1f),

    transitionSpec = {

        if (targetState > initialState) {

            (slideInHorizontally { it } togetherWith

                    slideOutHorizontally { -it / 2 } + veilOut(targetColor = veilColor))

        } else {

            slideInHorizontally { -it / 2 } +

                    unveilIn(initialColor = veilColor) togetherWith slideOutHorizontally { it }

        }

    },

) { targetPage ->

    ...

}

Những thay đổi sắp tới

Ngừng sử dụng Modifier.onFirstVisible

Compose 1.9 đã giới thiệu Modifier.onVisibilityChanged và Modifier.onFirstVisible. Sau khi xem xét ý kiến phản hồi của bạn, chúng tôi nhận thấy rằng không thể tuân thủ hợp đồng của Modifier.onFirstVisible một cách xác định; cụ thể là khi một mục lần đầu tiên xuất hiện. Ví dụ: bố cục từng phần có thể loại bỏ các mục cuộn ra khỏi khung hiển thị, sau đó kết hợp lại các mục đó nếu chúng cuộn trở lại khung hiển thị. Trong trường hợp này, lệnh gọi lại onFirstVisible sẽ kích hoạt lại, vì đây là một mục mới được kết hợp. Hành vi tương tự cũng sẽ xảy ra khi bạn quay lại màn hình đã truy cập trước đó có chứa onFirstVisible. Do đó, chúng tôi đã quyết định ngừng sử dụng công cụ sửa đổi này trong bản phát hành Compose tiếp theo (1.11) và đề xuất di chuyển sang onVisibilityChanged. Xem tài liệu để biết thêm thông tin.

Điều phối coroutine trong các bài kiểm thử

Chúng tôi dự định thay đổi việc điều phối coroutine trong các bài kiểm thử để cải thiện tính không ổn định của bài kiểm thử và phát hiện thêm nhiều vấn đề. Hiện tại, các bài kiểm thử sử dụng UnconfinedTestDispatcher, khác với hành vi sản xuất; ví dụ: các hiệu ứng có thể chạy ngay lập tức thay vì được đưa vào hàng đợi. Trong bản phát hành trong tương lai, chúng tôi dự định giới thiệu một API mới sử dụng StandardTestDispatcher theo mặc định để phù hợp với hành vi sản xuất. Bạn có thể thử hành vi mới ngay bây giờ trong phiên bản 1.10:

@get:Rule // also createAndroidComposeRule, createEmptyComposeRule

val rule = createComposeRule(effectContext = StandardTestDispatcher())

Việc sử dụng StandardTestDispatcher sẽ đưa các tác vụ vào hàng đợi, vì vậy, bạn phải sử dụng các cơ chế đồng bộ hoá như composeTestRule.waitForIdle() hoặc composeTestRule.runOnIdle(). Nếu bài kiểm thử của bạn sử dụng runTest, bạn phải đảm bảo rằng runTest và quy tắc Compose của bạn dùng chung cùng một thực thể StandardTestDispatcher để đồng bộ hoá.

// 1. Create a SINGLE dispatcher instance

val testDispatcher = StandardTestDispatcher()



// 2. Pass it to your Compose rule

@get:Rule

val composeRule = createComposeRule(effectContext = testDispatcher)



@Test

// 3. Pass the *SAME INSTANCE* to runTest

fun myTest() = runTest(testDispatcher) {

    composeRule.setContent { /* ... */ }

}

Công cụ

Các API tuyệt vời xứng đáng có các công cụ tuyệt vời và Android Studio có một số bổ sung gần đây dành cho nhà phát triển Compose:

Để xem các công cụ này hoạt động, hãy xem bản minh hoạ gần đây này:

Chúc bạn tạo thành phần vui vẻ

Chúng tôi tiếp tục đầu tư vào Jetpack Compose để cung cấp cho bạn các API và công cụ cần thiết để tạo giao diện người dùng đẹp mắt và phong phú. Chúng tôi 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 gì bạn muốn thấy tiếp theo trong trình theo dõi vấn đề của chúng tôi.

Tác giả:

Tiếp tục đọc