Neuigkeiten zum Produkt

Neuerungen in der Jetpack Compose-Version vom Dezember 2025

Lesezeit: 6 Minuten
Profil von Nick Butcher ansehen
Nick Butcher Product Manager

Die Jetpack Compose-Version vom Dezember 2025 ist jetzt stabil. Sie 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 die heutige Version 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. Diese Version 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 bei der Verwendung von Ansichten bietet:

janky.png

Benchmark zur Scrollleistung im Vergleich zwischen Ansichten 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 ausgelegt ist, Ruckeln bei hohen UI-Arbeitslasten deutlich 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 in Kombination mit Lazy-Layout-Prefetch, 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

Beibehalten

Compose bietet eine Reihe von APIs zum Beibehalten und Verwalten des Status über verschiedene Lebenszyklen hinweg. Mit remember wird beispielsweise der Status ü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. Sie ermöglicht es Ihnen, Werte über Konfigurationsänderungen hinweg beizubehalten, 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 und so zu verhindern, dass die Medienwiedergabe 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 beim 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 Auswahl und den 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-Versionen 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. Sie können 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 dieser Version 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 in diesem Videotipp: 

Anfangsgeschwindigkeit bei Übergängen für gemeinsame Elemente

Diese Version bietet 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 die halbtransparente Verhüllung (oder den Schleier) ü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 würde der onFirstVisible-Callback noch einmal ausgelöst, da es sich um ein neu zusammengesetztes Element handelt. Ein ähnliches Verhalten würde auch auftreten, wenn Sie zu einem zuvor besuchten Bildschirm mit onFirstVisible zurückkehren. Daher haben wir beschlossen, diesen Modifikator in der nächsten Compose-Version (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 einer zukünftigen Version 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:

In dieser aktuellen Demonstration können Sie sehen, wie diese Tools funktionieren:

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.

Geschrieben von:
Weiterlesen