Produktneuheiten

Neuerungen im Jetpack Compose-Release vom Dezember 2025

Lesezeit: 6 Minuten
Nick Butcher
Product Manager

Das Jetpack Compose-Release vom Dezember 2025 ist jetzt stabil. Es enthält Version 1.10 der Compose-Kernmodule und Version 1.4 von Material 3 (vollständige BOM-Zuordnung ansehen) und bietet neue Funktionen und erhebliche Leistungsverbesserungen.

Wenn Sie das Release von heute verwenden möchten, aktualisieren Sie Ihre Compose-BOM-Version auf 2025.12.00:

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

Leistungsverbesserungen

Wir wissen, dass die Laufzeitleistung Ihrer App für Sie und Ihre Nutzer von großer Bedeutung ist. Daher hat das Compose-Team der Leistung höchste Priorität eingeräumt. Dieses Release bietet eine Reihe von Verbesserungen, die Sie alle erhalten, indem Sie einfach auf die neueste Version aktualisieren. Unsere internen Scroll-Benchmarks zeigen, dass Compose jetzt die gleiche Leistung wie Views bietet:

janky.png

Benchmark zur Scrollleistung im Vergleich zwischen Views und Jetpack Compose in verschiedenen Versionen von Compose

Pausierbare Komposition bei Lazy Prefetch

Die pausierbare Komposition bei Lazy Prefetch ist jetzt standardmäßig aktiviert. Dies ist eine grundlegende Änderung der Funktionsweise der Compose-Laufzeitplanung, die darauf abzielt, Verzögerungen bei hohen UI-Arbeitslasten erheblich zu reduzieren.

Bisher musste eine Komposition nach dem Start bis zum Ende ausgeführt werden. Wenn eine Komposition komplex war, konnte dies den Hauptthread länger als ein einzelnes Frame blockieren, was dazu führte, dass die Benutzeroberfläche einfriert. Mit der pausierbaren Komposition kann die Laufzeit ihre Arbeit jetzt „pausieren“, wenn die Zeit knapp wird, und die Arbeit im nächsten Frame fortsetzen. Dies ist besonders effektiv, wenn es mit Lazy Layout Prefetch verwendet wird, um Frames im Voraus vorzubereiten. Die in Compose 1.9 eingeführten Lazy Layout CacheWindow APIs sind eine hervorragende Möglichkeit, mehr Inhalte vorab abzurufen und von der pausierbaren Komposition zu profitieren, um eine viel flüssigere UI-Leistung zu erzielen.

pausable.gif

Pausierbare Komposition in Kombination mit Lazy Prefetch trägt dazu bei, Verzögerung zu reduzieren

Wir haben die Leistung auch an anderen Stellen optimiert, z. B. durch Verbesserungen an Modifier.onPlaced, Modifier.onVisibilityChanged und anderen Modifikatorimplementierungen. Wir werden weiterhin in die Verbesserung der Leistung von Compose investieren.

Neue Funktionen

Retain

Compose bietet eine Reihe von APIs zum Beibehalten und Verwalten des Status über verschiedene Lebenszyklen hinweg. Mit remember wird der Status beispielsweise über Kompositionen hinweg beibehalten und mit rememberSavable/rememberSerializable über die Neuerstellung von Aktivitäten oder Prozessen hinweg.retain ist eine neue API, die zwischen diesen APIs liegt. Damit können Sie Werte über Konfigurationsänderungen hinweg beibehalten, ohne sie zu serialisieren, aber nicht über das Beenden von Prozessen hinweg. Da retain den Status nicht serialisiert, können Sie Objekte wie Lambda-Ausdrücke, Flows und große Objekte wie Bitmaps beibehalten, die nicht einfach serialisiert werden können. Sie können retain beispielsweise verwenden, um einen Media Player (z. B. ExoPlayer) zu verwalten, damit die Medienwiedergabe nicht durch eine Konfigurationsänderung unterbrochen wird.

@Composable

fun MediaPlayer() {

    val applicationContext = LocalContext.current.applicationContext

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

    ...

}

Wir möchten uns bei der AndroidDev-Community (insbesondere dem Circuit-Team) bedanken, die das Design dieser Funktion beeinflusst und dazu beigetragen hat.

Material 1.4

Version 1.4.0 der material3-Bibliothek bietet eine Reihe neuer Komponenten und Verbesserungen:

  • TextField bietet jetzt eine experimentelle TextFieldState-basierte Version, die eine robustere Methode zum Verwalten des Textstatus bietet. Außerdem werden jetzt neue Varianten von SecureTextField und OutlinedSecureTextField angeboten. Die Material-Composable Text unterstützt jetzt das Verhalten „AutoSize“.
  • Die Karussellkomponente bietet jetzt eine neue HorizontalCenteredHeroCarousel Variante.
  • TimePicker unterstützt jetzt das Umschalten zwischen der Picker- und der Eingabemodi.
  • Ein vertikaler Ziehpunkt ermöglicht es Nutzern, die Größe und/oder Position eines adaptiven Bereichs zu ändern.
centered-hero-carousel.webp

Horizontal zentriertes Hero-Karussell

Beachten Sie, dass Material 3 Expressive APIs weiterhin in den Alpha-Releases der material3 Bibliothek entwickelt werden. Weitere Informationen finden Sie in diesem aktuellen Vortrag:

Neue Animationsfunktionen

Wir erweitern unsere Animations-APIs weiter, einschließlich Updates zum Anpassen von Animationen für gemeinsame Elemente.

Dynamische gemeinsame Elemente

Standardmäßig versuchen die Animationen sharedElement() und sharedBounds(),

Layoutänderungen zu animieren, wenn im Zielstatus ein übereinstimmender Schlüssel gefunden wird. Möglicherweise möchten Sie diese Animation jedoch dynamisch deaktivieren, je nach bestimmten Bedingungen wie der Navigationsrichtung oder dem aktuellen UI-Status.

Um zu steuern, ob der Übergang des gemeinsamen Elements stattfindet, können Sie jetzt die SharedContentConfig anpassen, die an rememberSharedContentState() übergeben wird. Die Eigenschaft isEnabled bestimmt, ob das gemeinsame Element aktiv ist.

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

                }

            }

}

Weitere Informationen finden Sie in der Dokumentation.

Modifier.skipToLookaheadPosition()

In diesem Release wurde ein neuer Modifikator Modifier.skipToLookaheadPosition() hinzugefügt, der die endgültige Position einer Composable beibehält, wenn Animationen für gemeinsame Elemente ausgeführt werden. So können Übergänge wie Animationen vom Typ „Reveal“ ausgeführt werden, wie im Androidify-Beispiel mit der progressiven Enthüllung der Kamera zu sehen ist. Weitere Informationen finden Sie im Videotipp: 

Anfangsgeschwindigkeit bei Übergängen für gemeinsame Elemente

Dieses Release enthält eine neue API für Übergänge für gemeinsame Elemente, prepareTransitionWithInitialVelocity, mit der Sie eine Anfangsgeschwindigkeit (z.B. aus einer Geste) an einen Übergang für gemeinsame Elemente übergeben können:

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

Ein Übergang für gemeinsame Elemente, der mit einer Anfangsgeschwindigkeit aus einer Geste beginnt

Verhüllte Übergänge

EnterTransition und ExitTransition definieren, wie eine AnimatedVisibility/AnimatedContent-Composable angezeigt oder ausgeblendet wird. Mit einer neuen experimentellen Option können Sie eine Farbe angeben, um Inhalte zu verhüllen oder zu verdecken, z.B. durch Ein- und Ausblenden einer halbtransparenten schwarzen Ebene über Inhalten:

veil_2.gif

Verhüllte animierte Inhalte – beachten Sie den halbtransparenten Schleier (oder die Abdeckung) über den Rasterinhalten während der Animation

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

    ...

}

Anstehende Änderungen

Einstellung von Modifier.onFirstVisible

In Compose 1.9 wurden Modifier.onVisibilityChanged und Modifier.onFirstVisible eingeführt. Nach der Überprüfung Ihres Feedbacks wurde deutlich, dass der Vertrag von Modifier.onFirstVisible nicht deterministisch eingehalten werden konnte, insbesondere wenn ein Element zum ersten Mal sichtbar wird. Ein Lazy Layout kann beispielsweise Elemente entfernen, die aus dem Darstellungsbereich gescrollt werden, und sie dann wieder zusammensetzen, wenn sie wieder in den Darstellungsbereich gescrollt werden. In diesem Fall wird der onFirstVisible-Callback noch einmal ausgelöst, da es sich um ein neu zusammengesetztes Element handelt. Ein ähnliches Verhalten tritt auch auf, wenn Sie zu einem zuvor besuchten Bildschirm zurückkehren, der onFirstVisible enthält. Daher haben wir beschlossen, diesen Modifikator im nächsten Compose-Release (1.11) einzustellen und empfehlen, zu onVisibilityChanged zu migrieren. Weitere Informationen finden Sie in der Dokumentation.

Coroutine-Dispatch in Tests

Wir planen, den Coroutine-Dispatch in Tests zu ändern, um die Zuverlässigkeit von Tests zu verbessern und mehr Probleme zu erkennen. Derzeit verwenden Tests den UnconfinedTestDispatcher, der sich vom Produktionsverhalten unterscheidet. So werden Effekte beispielsweise möglicherweise sofort ausgeführt, anstatt in die Warteschlange gestellt zu werden. In einem zukünftigen Release planen wir, eine neue API einzuführen, die standardmäßig StandardTestDispatcher verwendet, um dem Produktionsverhalten zu entsprechen. Sie können das neue Verhalten jetzt in Version 1.10 testen:

@get:Rule // also createAndroidComposeRule, createEmptyComposeRule

val rule = createComposeRule(effectContext = StandardTestDispatcher())

Bei Verwendung von StandardTestDispatcher werden Aufgaben in die Warteschlange gestellt. Daher müssen Sie Synchronisierungsmechanismen wie composeTestRule.waitForIdle() oder composeTestRule.runOnIdle() verwenden. Wenn Ihr Test runTest verwendet, müssen Sie darauf achten, dass runTest und Ihre Compose-Regel dieselbe StandardTestDispatcher-Instanz für die Synchronisierung verwenden.

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

}

Tools

Hervorragende APIs verdienen hervorragende Tools. Android Studio bietet eine Reihe neuer Funktionen für Compose-Entwickler:

Eine Demonstration dieser Tools finden Sie in diesem aktuellen Video:

Viel Spaß beim Entwickeln mit Compose

Wir investieren weiterhin in Jetpack Compose, um Ihnen die APIs und Tools zur Verfügung zu stellen, die Sie zum Erstellen ansprechender, umfangreicher Benutzeroberflächen benötigen. Wir freuen uns über Ihr Feedback. Teilen Sie uns daher bitte in unserem Issue Tracker mit, was Sie von diesen Änderungen halten oder was Sie sich als Nächstes wünschen.

Verfasst von:

Weiterlesen