Nouveautés produit

Nouveautés de la version d'août 2026 de Jetpack Compose

Temps de lecture : 5 min
Afficher le profil de Nick Butcher
Nick Butcher Responsable produit

La version d'août 2026 de Jetpack Compose est désormais stable. Cette version apporte la version 1.12 aux modules Compose principaux (consultez le mapping BOM complet). Elle introduit des API visuelles riches telles que les dégradés de maillage et la prise en charge de la large gamme de couleurs (WCG, Wide Color Gamut), des fonctionnalités de mise en page structurelle telles que les zones nommées dans Grid, une intégration fluide avec le Gestionnaire d'identifiants d'Android, ainsi que des améliorations significatives en termes de tests et de performances.

Pour mettre à jour votre projet vers la version d'aujourd'hui, mettez à niveau votre version de Compose BOM vers 2026.08.00 :

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

Modifications destructives

  • AGP et Compile SDK : Compose 1.12 met à jour compileSdk vers l'API 37, ce qui nécessite un AGP 9.1.2 minimum. Pour rappel, Compose ciblera toujours la dernière version de compileSdk. Pour en savoir plus sur ce changement, cliquez ici.
  • Modifier.onFirstVisible() est obsolète : migrez vers Modifier.onVisibilityChanged(), qui permet un suivi plus précis du seuil de visibilité.

Graphismes

Dégradés de maillage

Compose 1.12 introduit MeshGradientPainter pour vous aider à créer des dégradés de couleurs organiques à plusieurs points.

meshGradient.gif
val rows = 1
val columns = 1

val gradientPainter = remember {
    MeshGradientPainter(rows, columns) {
        // Parameters: row, column, position, color
        setVertex(0, 0, Offset(0f, 0f), Color.Red)     // Top-Left
        setVertex(0, 1, Offset(1f, 0f), Color.Blue)    // Top-Right
        setVertex(1, 0, Offset(0f, 1f), Color.Green)   // Bottom-Left
        setVertex(1, 1, Offset(1f, 1f), Color.Yellow)  // Bottom-Right
    }
}

Box(
    modifier = modifier
        .aspectRatio(16/9f)
        .fillMaxWidth()
        .paint(gradientPainter)
)

Pour en savoir plus et obtenir des exemples, consultez la documentation.

Large gamme de couleurs et compatibilité HDR

Les écrans modernes offrent une fidélité des couleurs étendue et une plage dynamique plus élevée. Dans Compose 1.12, la prise en charge complète du pipeline pour la large gamme de couleurs (P3) et le rendu HDR a été activée dans les graphiques, la peinture et les nuanceurs Compose. Les couleurs définies dans des espaces colorimétriques non sRVB (tels que Display P3) sont conservées jusqu'au rendu de la plate-forme, sans limitation de couleur. Les couleurs reviendront à sRVB si elles utilisent un espace colorimétrique non compatible (par exemple, CieXyz, CieLab ou Oklab), si elles s'appuient sur un espace colorimétrique sur une version d'Android non compatible (par exemple, Bt2020Hlg sur Android 13 et versions antérieures) ou si l'application s'exécute sur Android 9 (API 28) et versions antérieures.

Autres changements notables :

  • LayerOutsets a été ajouté à GraphicsLayer et Modifier.graphicsLayer. Vous pouvez l'utiliser pour augmenter les limites visuelles du calque au-delà de sa taille mesurée. Appliquez LayerOutsets pour éviter le comportement clipToBounds implicite lorsque le calque est promu dans un tampon hors écran.

Styles

Lors de Google I/O, nous avons présenté notre première vision de l'API Styles de Compose, qui offre un moyen unifié et performant de styliser les composants. Depuis, nous avons continué à développer l'architecture sous-jacente pour garantir une sûreté du typage stricte et une correction prévisible, et pour permettre la création de systèmes de conception personnalisés. 

Pour nous assurer que cette couche fondamentale est correcte, l'API restera expérimentale et vous pouvez vous attendre à des changements majeurs. 

Optimisations d'exécution

Surcharge KeyedSideEffect

SideEffect prend désormais en charge les arguments clés, ce qui vous permet de déclencher des effets secondaires ponctuels chaque fois que des clés spécifiques changent. Cela peut améliorer les performances par rapport à l'utilisation d'un LaunchedEffect ou d'un DisposableEffect lorsque vous n'avez pas besoin du bloc de coroutine ou de suppression. SideEffect est jusqu'à 90% plus rapide que LaunchedEffect et environ 20% plus rapide que DisposableEffect. Notez que SideEffect exécute son effet avant DisposableEffect et LaunchedEffect. Soyez donc prudent si vous migrez des effets existants vers cette API, en particulier pour les LaunchedEffects qui doivent être distribués pour démarrer après la fin de la frame actuelle.

@Composable
fun AnalyticsTracker(userId: String, screenName: String) {
    SideEffect(key1 = userId, key2 = screenName) {
        analytics.logScreenView(userId, screenName)
    }
}

Animation

Transitions interactives en deux étapes

  • Nouveaux composables : DeferredAnimatedContent et DeferredAnimatedVisibility permettent de créer des transitions en deux étapes agréables, par exemple pour le suivi du geste de prévisualisation du Retour.
  • Contrôle manuel de l'animation : pendant la phase différée d'une transition, les propriétés animées (comme l'échelle ou le décalage) peuvent désormais être manipulées manuellement en temps réel (par exemple, en suivant un geste de balayage).
  • Transfert fluide : une fois la phase différée terminée, le moteur de transition prend le relais et effectue un transfert fluide, y compris le transfert de vitesse, vers la transition automatique.
  • Compatibilité avec les éléments partagés : un nouveau flag permitTransformDuringDeferredTransition dans SharedContentConfig contrôle si les éléments partagés se transforment visuellement avec leurs conteneurs parents pendant la phase de transition différée.
val state = remember { DeferredTransitionState(initialScreen) }
val transition = rememberDeferredTransition(state)

if (predictiveBackInProgress) {
    state.defer(targetScreen)
} else {
    state.animateTo(targetScreen)
}

transition.DeferredAnimatedContent(
    targetState = targetScreen,
    mutableTransformSpec = {
       MutableContentTransform {
           // Manually manipulate properties during the deferred phase
           initialContentTransform { scale = swipeProgress }
       }
    }
) { screen ->
    ScreenContent(screen)
}

Vous trouverez ci-dessous deux démonstrations de cas d'utilisation dans lesquels une animation déclenchée par un geste est transmise à une animation déclenchée :

colorCards.gif

Intégrations de texte, de saisie et de plate-forme

Mise en forme de texte modifiable

De nouvelles API offrent une mise en forme enrichie pour le texte modifiable dans BasicTextField. Vous pouvez désormais appliquer et manipuler la mise en forme des caractères et des paragraphes de façon programmatique à l'aide de SpanStyle et ParagraphStyle via la nouvelle méthode addStyle() dans une portée TextFieldBuffer (comme dans textFieldState.edit { ... } ou InputTransformation). De plus, TextFieldBuffer fournit les API getSpanStyles() et getParagraphStyles() qui renvoient des objets TrackedRange, ce qui vous permet de lire, de mettre à jour ou de supprimer les styles appliqués. Pour compléter la création de mise en forme, TextFieldState expose désormais une propriété textStyles en lecture seule permettant d'interroger les styles actifs dans les plages, tandis que TextFieldBuffer fournit originalTextStyles pour inspecter l'état de la mise en forme avant une modification. La mise en forme du texte et les annotations personnalisées sont conservées lors des modifications de configuration.

val state = rememberTextFieldState("Formatted text in Compose 1.12")

// Apply bold and color styles to a range of text
state.edit {
    addStyle(
        SpanStyle(fontWeight = FontWeight.Bold, color = Color.Blue),
        start = 0,
        end = 9
    )
}

// Query active styles from TextFieldState
val currentStyles = state.textStyles

Sélection de texte

Une nouvelle API SelectionState offre un contrôle programmatique et une observabilité de la sélection de texte dans un SelectionContainer. L'élévation d'un objet SelectionState via rememberSelectionState() et sa transmission à SelectionContainer expose selectedTexts en tant que liste réactive de AnnotatedStrings et fournit des méthodes telles que selectAll(), clear(), select(TextRange) et extendSelectionByWord().

De plus, utilisez getSelectableTexts() pour récupérer tous les éléments de texte sélectionnables dans l'ordre de mise en page et sélectionnez le texte dans les composables de SelectionContainer à l'aide d'une plage globale. 

@Composable
fun ProgrammaticSelectionExample() {
    val selectionState = rememberSelectionState()

    Column {
        Button(
            onClick = { selectionState.selectAll() },
            modifier = Modifier.disableSelectionClearOnTap()
        ) {
            Text("Select All")
        }

        SelectionContainer(state = selectionState) {
            Text("Text content to be selected programmatically.")
        }
    }
}

Intégration du Gestionnaire d'identifiants

Les champs de texte Compose s'intègrent désormais de manière native à Credential Manager d'Android (API 34 et versions ultérieures) via le framework de saisie automatique (les versions antérieures à l'API 34 sont gérées par androidx.credentials library). En associant la nouvelle propriété sémantique credentialRequest avec CredentialRequestData, les saisies de texte peuvent déclencher des clés d'accès, des identifiants enregistrés ou des demandes de connexion directement dans le flux d'entrée utilisateur.

@Composable
fun LoginField(textFieldState: TextFieldState) {
    val credentialData = remember {
        CredentialRequestData(
            // Specify Credential Manager request options
        )
    }

    BasicTextField(
        state = textFieldState,
        modifier = Modifier.semantics {
            credentialRequest = credentialData
        }
    )
}

Autres changements notables :

  • Prise en charge des paramètres de variante de police dans les polices téléchargeables.
  • Activation du défilement automatique lors du déplacement de la sélection de texte au-delà de la fenêtre d'affichage dans SelectionContainer.
  • Ajout de la prise en charge des sons d'interaction automatique (clics et navigation au clavier) aux composants Compose, avec un nouveau composable SoundEffectOnInteraction pour permettre la désactivation. Notez qu'en raison de ce changement, les écouteurs de clics sémantiques doivent désormais être appelés à partir du thread principal, ce qui peut affecter un petit nombre de cas de test.
  • KeyboardType inclut désormais Date, Time, DateTime et SignedDecimal.
  • BasicSecureTextField utilise désormais TextObfuscationMode.System par défaut, tandis que RevealLastTyped sert de remplacement absolu.

Améliorations de la mise en page

Zones nommées dans la mise en page sous forme de grille

Il est désormais plus facile de créer des mises en page 2D complexes grâce aux zones nommées dans le composant Grid de @Experimental. Plutôt que de gérer les index numériques des colonnes et des lignes pour les éléments, vous pouvez définir des régions sémantiques dans votre GridConfigurationScope et positionner les composables par nom de zone.

@OptIn(ExperimentalGridApi::class)
@Composable
fun DashboardLayout() {
    Grid(
        config = {
            area("header", row = 0, column = 0, rowSpan = 1, columnSpan = 2)
            area("sidebar", row = 1, column = 0)
            area("content", row = 1, column = 1)
            gap(16.dp)
        }
    ) {
        HeaderSection(modifier = Modifier.gridItem(areaId = "header"))
        NavigationSidebar(modifier = Modifier.gridItem(areaId = "sidebar"))
        MainContentView(modifier = Modifier.gridItem(areaId = "content"))
    }
}

Pour en savoir plus, consultez la documentation.

Performances

Comme pour chaque version, nous continuons d'investir dans les performances de Compose pour nous assurer que le framework vous aide à créer des applications esthétiques et performantes. Dans cette version, nous nous sommes concentrés sur l'amélioration des performances de démarrage. Nous constatons désormais un délai d'affichage initial (temps nécessaire à une application pour produire son premier frame) comparable à celui des vues dans nos benchmarks.

timetoinitialdisplay@2x _v2.png

Mises à niveau des outils et des tests

Tester la synchronisation

Compose 1.12 introduit de nouvelles API de test conçues pour réduire les temps d'exécution des tests et éliminer l'instabilité lors de l'échantillonnage d'état :

  • hasPendingWork : vérifie passivement si l'UI a du travail en attente sans faire avancer l'horloge, ce qui est idéal pour les boucles d'animation manuelles.
  • runWithoutImplicitWait : désactive temporairement la synchronisation implicite lors du parcours des frames d'horloge manuelle (par exemple, les tests d'animation).
@Test
fun testAnimationStateFast() {

composeTestRule.mainClock.autoAdvance = false
    
    while (composeTestRule.hasPendingWork()) {
        composeTestRule.mainClock.advanceTimeByFrame()
        composeTestRule.waitForIdle()
        
        composeTestRule.runOnUiThread {
            composeTestRule.runWithoutImplicitWait {
                // This is most effective when querying multiple nodes in a single frame. 
                // It prevents the redundant synchronization overhead that would 
                // otherwise occur on every individual query.
                val box1 = composeTestRule.onNodeWithTag("Box1").fetchSemanticsNode()
                val box2 = composeTestRule.onNodeWithTag("Box2").fetchSemanticsNode()
                
                assertThat(box1.boundsInRoot.right).isAtMost(box2.boundsInRoot.left)
            }
        }
    }
}

Autres changements notables :

  • L'API captureToImage vous permet désormais de capturer un pop-up ou une boîte de dialogue avec son ancrage dans un seul bitmap.
  • Ajout de onRootWithViewInteraction pour limiter les recherches sémantiques Compose à des vues Android spécifiques. Cela simplifie le test des UI hybrides, telles que RecyclerViews, sans nécessiter de tags de test uniques dans le code de production.
  • Les annotations @PreviewWrapper peuvent désormais être appliquées aux classes @MultiPreview personnalisées, ce qui permet de réutiliser des configurations d'aperçu (comme des thèmes personnalisés) sur plusieurs composants.

Bonne composition !

Compose 1.12 facilite et enrichit le développement d'applications grâce aux dégradés de maillage, à la prise en charge d'une large gamme de couleurs, aux polices variables téléchargeables, à l'intégration du Credential Manager et à des outils de test plus rapides. Comme toujours, vos commentaires sont importants. N'hésitez pas à nous les envoyer pour nous faire part de vos impressions sur ces modifications ou de ce que vous aimeriez voir ensuite sur notre outil de suivi des problèmes. À vos claviers !

Écrit par :
Continuer la lecture