Nowości dotyczące usług

Co nowego w wersji Jetpack Compose z grudnia 2025 r.

Czas czytania: 6 min
Wyświetl profil Nicka Butchera
Nick Butcher Menedżer produktu

Wersja Jetpack Compose z grudnia 2025 r. jest już stabilna. Zawiera ona wersję 1.10 podstawowych modułów Compose i wersję 1.4 Material 3 (pełne mapowanie BOM), a także nowe funkcje i znaczące ulepszenia wydajności.

Aby korzystać z dzisiejszej wersji, zaktualizuj wersję BOM Compose do 2025.12.00:

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

Ulepszenia wydajności

Wiemy, że wydajność aplikacji w czasie działania jest niezwykle ważna dla Ciebie i Twoich użytkowników, dlatego zespół Compose przykłada do niej dużą wagę. Ta wersja wprowadza szereg ulepszeń, które uzyskasz, po prostu aktualizując aplikację do najnowszej wersji. Nasze wewnętrzne testy porównawcze przewijania pokazują, że Compose osiąga teraz wydajność porównywalną z wydajnością widoków:

janky.png

Test porównawczy wydajności przewijania porównujący widoki i Jetpack Compose w różnych wersjach Compose

Kompozycja z możliwością wstrzymania w przypadku leniwego pobierania z wyprzedzeniem

Kompozycja z możliwością wstrzymania w przypadku leniwego pobierania z wyprzedzeniem jest teraz domyślnie włączona. Jest to fundamentalna zmiana w sposobie działania harmonogramu Compose, która ma na celu znaczne zmniejszenie zacięć podczas intensywnej pracy interfejsu.

Wcześniej po rozpoczęciu kompozycji musiała ona zostać ukończona. Jeśli kompozycja była złożona, mogła blokować wątek główny przez dłużej niż jedną klatkę, co powodowało zawieszanie się interfejsu. Dzięki kompozycji z możliwością wstrzymania środowisko wykonawcze może teraz „wstrzymać” pracę, jeśli zabraknie mu czasu, i wznowić ją w następnej klatce. Jest to szczególnie skuteczne w przypadku użycia z leniwym pobieraniem z wyprzedzeniem, aby przygotować klatki z wyprzedzeniem. Interfejsy API Lazy layout CacheWindow wprowadzone w Compose 1.9 to świetny sposób na pobieranie większej ilości treści z wyprzedzeniem i korzystanie z kompozycji z możliwością wstrzymania, aby uzyskać znacznie płynniejsze działanie interfejsu.

pausable.gif

Kompozycja z możliwością wstrzymania w połączeniu z leniwym pobieraniem z wyprzedzeniem pomaga zmniejszyć zacięcia

Zoptymalizowaliśmy też wydajność w innych miejscach, wprowadzając ulepszenia w Modifier.onPlaced, Modifier.onVisibilityChanged i innych implementacjach modyfikatorów. Będziemy nadal inwestować w poprawę wydajności Compose.

Nowe funkcje

Retain

Compose oferuje szereg interfejsów API do przechowywania stanu i zarządzania nim w różnych cyklach życia. Na przykład remember zachowuje stan w różnych kompozycjach, a rememberSavable/rememberSerializable – w przypadku ponownego utworzenia aktywności lub procesu.retain to nowy interfejs API, który znajduje się między tymi interfejsami API i umożliwia zachowywanie wartości w przypadku zmian konfiguracji bez serializacji, ale nie w przypadku zakończenia procesu. Ponieważ retain nie serializuje stanu, możesz zachowywać obiekty takie jak wyrażenia lambda, przepływy i duże obiekty, np. mapy bitowe, których nie można łatwo serializować. Możesz na przykład użyć retain do zarządzania odtwarzaczem multimediów (np. ExoPlayer), aby zapewnić, że odtwarzanie multimediów nie zostanie przerwane przez zmianę konfiguracji.

@Composable

fun MediaPlayer() {

    val applicationContext = LocalContext.current.applicationContext

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

    ...

}

Chcemy podziękować społeczności AndroidDev (zwłaszcza zespołowi Circuit), która miała wpływ na projekt tej funkcji i przyczyniła się do jej powstania.

Material 1.4

Wersja 1.4.0 biblioteki material3 dodaje szereg nowych komponentów i ulepszeń:

centered-hero-carousel.webp

Karuzela pozioma wyśrodkowana

Pamiętaj, że interfejsy API Material 3 Expressive są nadal rozwijane w wersjach alfa biblioteki material3. Więcej informacji znajdziesz w tym niedawnym wystąpieniu:

Nowe funkcje animacji

Stale rozwijamy nasze interfejsy API animacji, w tym aktualizacje umożliwiające dostosowywanie animacji elementów współdzielonych.

Dynamiczne elementy współdzielone

Domyślnie animacje sharedElement() i sharedBounds() próbują animować

zmiany układu, gdy w stanie docelowym zostanie znaleziony pasujący klucz. Możesz jednak wyłączyć tę animację dynamicznie na podstawie określonych warunków, takich jak kierunek nawigacji lub bieżący stan interfejsu.

Aby kontrolować, czy ma wystąpić przejście elementu współdzielonego, możesz teraz dostosować SharedContentConfig przekazywany do rememberSharedContentState(). Właściwość isEnabled określa, czy element współdzielony jest aktywny.

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

                }

            }

}

Więcej informacji znajdziesz w dokumentacji.

Modifier.skipToLookaheadPosition()

W tej wersji dodaliśmy nowy modyfikator Modifier.skipToLookaheadPosition(), który zachowuje ostateczne położenie komponentu podczas wykonywania animacji elementów współdzielonych. Umożliwia to wykonywanie przejść, takich jak animacja typu „reveal”, co widać w przykładzie Androidify z progresywnym ujawnianiem aparatu. Więcej informacji znajdziesz w tej wskazówce wideo: 

Prędkość początkowa w przejściach elementów współdzielonych

Ta wersja dodaje nowy interfejs API przejścia elementu współdzielonego, prepareTransitionWithInitialVelocity, który umożliwia przekazywanie prędkości początkowej (np. z gestu) do przejścia elementu współdzielonego:

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

Przejście elementu współdzielonego, które rozpoczyna się z prędkością początkową z gestu

Przejścia z zasłoną

EnterTransitionExitTransition określają, jak komponent AnimatedVisibility/AnimatedContent pojawia się lub znika. Nowa eksperymentalna opcja zasłony umożliwia określenie koloru, który ma zasłaniać lub przyciemniać treści. Możesz na przykład stopniowo wyświetlać lub ukrywać półprzezroczystą czarną warstwę nad treścią:

veil_2.gif

Animowana treść z zasłoną – podczas animacji widoczna jest półprzezroczysta zasłona (lub przyciemnienie) nad treścią siatki

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 ->

    ...

}

Nadchodzące zmiany

Wycofanie Modifier.onFirstVisible

W Compose 1.9 wprowadziliśmy Modifier.onVisibilityChangedModifier.onFirstVisible. Po przeanalizowaniu Waszych opinii okazało się, że nie można deterministycznie spełnić warunków Modifier.onFirstVisible, zwłaszcza gdy element po raz pierwszy staje się widoczny. Na przykład układ leniwy może usuwać elementy, które przewijają się poza obszar widoczny, a następnie ponownie je komponować, jeśli przewiną się z powrotem do widoku. W takiej sytuacji wywoływane jest ponownie wywołanie zwrotne onFirstVisible, ponieważ jest to nowo skomponowany element. Podobne zachowanie występuje też w przypadku powrotu do wcześniej odwiedzonego ekranu zawierającego onFirstVisible. Z tego powodu zdecydowaliśmy się wycofać ten modyfikator w następnej wersji Compose (1.11) i zalecamy przejście na onVisibilityChanged. Więcej informacji znajdziesz w dokumentacji.

Wysyłanie współprogramów w testach

Planujemy zmienić wysyłanie współprogramów w testach, aby zmniejszyć ich niestabilność i wykrywać więcej problemów. Obecnie testy używają UnconfinedTestDispatcher, który różni się od zachowania w środowisku produkcyjnym. Na przykład efekty mogą być wykonywane natychmiast, a nie dodawane do kolejki. W przyszłej wersji planujemy wprowadzić nowy interfejs API, który domyślnie będzie używać StandardTestDispatcher, aby dopasować zachowanie do środowiska produkcyjnego. Nowe zachowanie możesz wypróbować teraz w wersji 1.10:

@get:Rule // also createAndroidComposeRule, createEmptyComposeRule

val rule = createComposeRule(effectContext = StandardTestDispatcher())

Użycie StandardTestDispatcher spowoduje dodanie zadań do kolejki, dlatego musisz użyć mechanizmów synchronizacji, takich jak composeTestRule.waitForIdle() lub composeTestRule.runOnIdle(). Jeśli test używa runTest, musisz się upewnić, że runTest i reguła Compose współdzielą tę samą instancję StandardTestDispatcher na potrzeby synchronizacji.

// 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 { /* ... */ }

}

Narzędzia

Świetne interfejsy API zasługują na świetne narzędzia, a Android Studio ma kilka nowych funkcji dla deweloperów Compose:

Aby zobaczyć te narzędzia w akcji, obejrzyj tę niedawną prezentację:

Przyjemnego komponowania

Stale inwestujemy w Jetpack Compose, aby zapewnić Ci interfejsy API i narzędzia potrzebne do tworzenia pięknych i bogatych interfejsów. Cenimy Twoje opinie, dlatego podziel się nimi na temat tych zmian lub tego, co chcesz zobaczyć w przyszłości, w naszym narzędziu do śledzenia problemów.

Czytaj dalej