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 bản đồ BOM đầy đủ), 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 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 luôn 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 điểm chuẩn 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

Điểm chuẩn hiệu suất cuộn so sánh Chế độ xem và Jetpack Compose trên nhiều phiên bản Compose

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

Thành phần có thể tạm dừng trong tính năng tìm nạp trước lazy 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 nặng về giao diện người dùng.

Trước đây, sau khi bắt đầu, một thành phần phải chạy cho đến khi hoàn tất. Nếu một 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ị treo. 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 lazy để chuẩn bị trước các khung hình. Các API CacheWindow bố cục Lazy đượ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 Lazy 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 những điểm cải thiện đối với Modifier.onPlaced, Modifier.onVisibilityChanged và các cách triển khai đối tượng sửa đổi khác. Chúng tôi sẽ tiếp tục đầu tư vào việc 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 nhiều vòng đời; 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 chuyển đổi tuần tự, nhưng không duy trì trên quá trình bị buộc tắt. Vì retain không tuần tự hoá 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 mà không thể dễ dàng tuần tự hoá. Ví dụ: bạn có thể sử dụng retain để quản lý trình phát nội dung nghe nhìn (chẳng hạn như ExoPlayer) nhằm đảm bảo rằng quá trình phát nội dung nghe nhìn không bị gián đoạn do thay đổi cấu hình.

  @Composable

fun MediaPlayer() {

    val applicationContext = LocalContext.current.applicationContext

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

    ...

}

Chúng tôi xin 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 TextFieldState thử nghiệm, 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 material hiện hỗ trợ hành vi autoSize.
  • Thành phần băng chuyền hiện cung cấp biến thể HorizontalCenteredHeroCarousel mới.
  • TimePicker hiện hỗ trợ chuyển đổi giữa bộ chọn và chế độ nhập.
  • Một tay cầm 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 chính giữa theo chiều ngang

Xin lưu ý rằng API Biểu đạt 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 thành phần dùng chung.

Các thành phần dùng chung động

Theo mặc định, ảnh động sharedElement()sharedBounds() sẽ 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 thành phần 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 thành phần 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 thông tin.

Modifier.skipToLookaheadPosition()

Một đối tượng sửa đổi mới, Modifier.skipToLookaheadPosition(), đã được thêm vào 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 thành phần dùng chung. Điều này cho phép thực hiện các chuyển đổi như ảnh động kiểu "tiết lộ", như bạn có thể thấy trong mẫu Androidify với tính năng tiết lộ 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 thành phần dùng chung

Bản phát hành này bổ sung một API chuyển đổi thành phần 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 thành phần 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 thành phần 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 ảnh độ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ể thực hiện 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 Lazy có thể loại bỏ các mục cuộn ra khỏi khung nhìn, sau đó kết hợp lại nếu các mục đó cuộn trở lại khung nhìn. 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 điều hướng 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 xếp 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ẽ xếp hàng đợi các tác vụ, 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 chia sẻ 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 trình bày 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