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.
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 :
LayerOutsetsa été ajouté àGraphicsLayeretModifier.graphicsLayer. Vous pouvez l'utiliser pour augmenter les limites visuelles du calque au-delà de sa taille mesurée. AppliquezLayerOutsetspour éviter le comportementclipToBoundsimplicite 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
DeferredTargetAnimationn'est plus au stade expérimental.
Transitions interactives en deux étapes
- Nouveaux composables :
DeferredAnimatedContentetDeferredAnimatedVisibilitypermettent 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
permitTransformDuringDeferredTransitiondansSharedContentConfigcontrô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 :
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
SoundEffectOnInteractionpour 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. KeyboardTypeinclut désormaisDate,Time,DateTimeetSignedDecimal.BasicSecureTextFieldutilise désormaisTextObfuscationMode.Systempar défaut, tandis queRevealLastTypedsert 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.
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
captureToImagevous permet désormais de capturer un pop-up ou une boîte de dialogue avec son ancrage dans un seul bitmap. - Ajout de
onRootWithViewInteractionpour limiter les recherches sémantiques Compose à des vues Android spécifiques. Cela simplifie le test des UI hybrides, telles queRecyclerViews, sans nécessiter de tags de test uniques dans le code de production. - Les annotations
@PreviewWrapperpeuvent désormais être appliquées aux classes@MultiPreviewpersonnalisé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 !
-
Nouveautés produitGooglebook est une nouvelle catégorie d'ordinateurs portables basés sur une plate-forme Android partagée. Le matériel hautes performances de partenaires tels que HP, Dell, Lenovo, Acer et Asus combine la praticité du mobile et la puissance d'un ordinateur de bureau.
Fahd Imtiaz, Loryn Hairston • Temps de lecture : 4 min -
Nouveautés produitAvec l'arrivée du Pixel 11 Pro Fold, de la Pixel Watch 5 et de toute la famille Pixel, les utilisateurs passent facilement d'une taille d'écran à une autre, adoptent des postures uniques et profitent d'expériences intelligentes.
Fahd Imtiaz, Loryn Hairston, Tracy Agyemang • Temps de lecture : 4 min -
Nouveautés produitAujourd'hui, nous célébrons officiellement les cinq ans de la sortie de Jetpack Compose 1.0. Depuis la version 1.0, annoncée le 28 juillet 2021, jusqu'à notre dernière version 1.11, nous avons constaté une évolution significative des API au fil des ans. Nous souhaitons donc prendre le temps de la célébrer.
Rebecca Franks, Nick Butcher, Loryn Hairston • Temps de lecture : 4 min
Recevez chaque semaine les dernières informations sur le développement Android directement dans votre boîte de réception.