Novedades de la versión de agosto de 2026 de Jetpack Compose
Lectura de 5 min
Hoy, la versión de agosto de 2026 de Jetpack Compose es estable. Esta versión incluye la versión 1.12 en los módulos principales de Compose (consulta la asignación completa de la BOM) y presenta APIs visuales enriquecidas, como Mesh Gradients y compatibilidad con Wide Color Gamut (WCG), funciones de diseño estructurales, como áreas con nombre en Grid, integración perfecta con Credential Manager de Android y mejoras significativas en las pruebas y el rendimiento.
Para actualizar tu proyecto a la versión de hoy, actualiza la versión de Compose BOM a 2026.08.00:
implementation(platform("androidx.compose:compose-bom:2026.08.00"))
Cambios rotundos
- AGP y SDK de compilación: Compose 1.12 actualiza compileSdk a la API 37, lo que requiere un AGP mínimo de 9.1.2. Como recordatorio, Compose siempre se orientará al compileSdk más reciente. Obtén más información sobre este cambio aquí.
Modifier.onFirstVisible()está obsoleta: Migra a Modifier.onVisibilityChanged(), que proporciona un seguimiento más preciso del umbral de visibilidad.
Gráficos
Mesh Gradients
Compose 1.12 presenta MeshGradientPainter para ayudarte a crear gradientes de color orgánicos de varios puntos.
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) )
Para obtener más información y ejemplos, consulta la documentación.
Compatibilidad con HDR y Wide Color Gamut
Las pantallas modernas ofrecen una fidelidad de color extendida y un rango dinámico más alto. En Compose 1.12, se habilitó la compatibilidad completa con la canalización para Wide Color Gamut (P3) y la renderización HDR en los gráficos, la pintura y los sombreadores de Compose. Los colores definidos en espacios de color que no son sRGB (como Display P3) se conservan hasta la renderización de la plataforma sin sujeción de color. Los colores volverán de forma segura a sRGB si usan un espacio de color no compatible (p. ej., CieXyz, CieLab o Oklab), dependen de un espacio de color en una versión de Android no compatible (p. ej., Bt2020Hlg en Android 13 y versiones anteriores) o si la app se ejecuta en Android 9 (API 28) y versiones anteriores.
Otros cambios destacados:
LayerOutsetsse agregó aGraphicsLayeryModifier.graphicsLayer, que puedes usar para aumentar los límites visuales de la capa más allá de su tamaño medido. AplicaLayerOutsetspara evitar el comportamientoclipToBoundsimplícito cuando la capa se promueve a un búfer fuera de la pantalla.
Estilos
En Google I/O, compartimos nuestra visión inicial de la API de Styles de Compose, una forma unificada y de alto rendimiento de diseñar componentes. Desde entonces, continuamos compilando la arquitectura subyacente para garantizar una seguridad de tipo estricta y una exactitud predecible, y para admitir la compilación de sistemas de diseño personalizados.
Para asegurarnos de que esta capa fundamental sea correcta, la API seguirá siendo experimental y puedes esperar cambios rotundos.
Optimizaciones del tiempo de ejecución
Sobrecarga SideEffect con clave
SideEffect ahora admite argumentos clave, lo que te permite activar efectos secundarios únicos cada vez que cambian claves específicas. Esto puede generar un mejor rendimiento en comparación con el uso de LaunchedEffect o DisposableEffect cuando no necesitas la corrutina ni el bloque de eliminación. SideEffect es hasta un 90% más rápido que LaunchedEffect y alrededor de un 20% más rápido que DisposableEffect. Ten en cuenta que SideEffect ejecuta su efecto antes que DisposableEffect y LaunchedEffect, por lo que debes tener cuidado si migras los efectos existentes a esta API, en especial para LaunchedEffects que dependen de que se envíen para comenzar después de que se complete el fotograma actual.
@Composable fun AnalyticsTracker(userId: String, screenName: String) { SideEffect(key1 = userId, key2 = screenName) { analytics.logScreenView(userId, screenName) } }
Animación
DeferredTargetAnimationdejó de ser experimental.
Transiciones interactivas de dos etapas
- Nuevos elementos componibles:
DeferredAnimatedContentyDeferredAnimatedVisibilitypermiten crear transiciones agradables de dos etapas, p.ej., para el seguimiento predictivo del gesto de retroceso. - Control manual de la animación: Durante la fase diferida de una transición, las propiedades animadas (como la escala o el desplazamiento) ahora se pueden manipular manualmente en tiempo real (p.ej., seguimiento de un gesto de deslizamiento).
- Transferencia fluida: Una vez que finaliza la fase diferida, el motor de transición toma el control y realiza una transferencia fluida, incluida la transferencia de velocidad, a la transición automática.
- Compatibilidad con elementos compartidos: Una nueva
permitTransformDuringDeferredTransitionmarca enSharedContentConfigcontrola si los elementos compartidos se transforman visualmente junto con sus contenedores superiores durante la fase de transición diferida.
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) }
A continuación, se incluyen dos demostraciones de casos de uso en los que una animación basada en gestos se transfiere a una animación activada:
Integraciones de texto, entrada y plataforma
Formato de texto editable
Las nuevas APIs ofrecen formato de texto enriquecido para texto editable en BasicTextField. Ahora puedes aplicar y manipular de forma programática el formato de caracteres y párrafos intercalados con SpanStyle y ParagraphStyle a través del nuevo método addStyle() dentro de un alcance TextFieldBuffer (como dentro de textFieldState.edit { ... } o una InputTransformation). Además, TextFieldBuffer proporciona APIs getSpanStyles() y getParagraphStyles() que muestran objetos TrackedRange, lo que te permite leer, actualizar o quitar estilos aplicados. Para complementar la creación de formato, TextFieldState ahora expone una propiedad textStyles de solo lectura para consultar estilos activos en rangos, mientras que TextFieldBuffer proporciona originalTextStyles para inspeccionar el estado de formato antes de una edición. El formato de texto y las anotaciones personalizadas se conservan en los cambios de configuración.
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
Selección de texto
Una nueva SelectionState API proporciona control programático y observabilidad sobre la selección de texto dentro de un SelectionContainer. Si se aloja un objeto SelectionState a través de rememberSelectionState() y se pasa a SelectionContainer, se expone selectedTexts como una lista reactiva de AnnotatedStrings y se proporcionan métodos como selectAll(), clear(), select(TextRange) y extendSelectionByWord().
Además, usa getSelectableTexts() para recuperar todos los elementos de texto seleccionables en orden de diseño y seleccionar texto en elementos componibles en SelectionContainer con un rango global.
@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.") } } }
Integración de Credential Manager
Los campos de texto de Compose ahora se integran de forma nativa con Credential Manager de Android (API 34+) a través del framework de Autofill (la API 34 se controla con androidx.credentials library). Si se adjunta la nueva propiedad semántica credentialRequest con CredentialRequestData, las entradas de texto pueden solicitar llaves de acceso, credenciales guardadas o solicitudes de acceso directamente dentro del flujo de entrada del usuario.
@Composable fun LoginField(textFieldState: TextFieldState) { val credentialData = remember { CredentialRequestData( // Specify Credential Manager request options ) } BasicTextField( state = textFieldState, modifier = Modifier.semantics { credentialRequest = credentialData } ) }
Otros cambios destacados:
- Compatibilidad con la configuración de variación de fuentes en fuentes descargables.
- Se habilitó el desplazamiento automático cuando se arrastra la selección de texto más allá de la ventana gráfica en
SelectionContainer. - Se agregó compatibilidad con sonidos de interacción automática (clics y navegación de enfoque) a los componentes de Compose, con un nuevo
SoundEffectOnInteractionelemento componible para permitir la exclusión. Ten en cuenta que, como consecuencia de este cambio, ahora se debe llamar a los objetos de escucha de clics semánticos desde el subproceso principal, lo que puede afectar una pequeña cantidad de casos de prueba. KeyboardTypeahora incluyeDate,Time,DateTime, ySignedDecimal.BasicSecureTextFieldahora usaTextObfuscationMode.Systemde forma predeterminada, mientras queRevealLastTypedsirve como anulación absoluta.
Mejoras en el diseño
Áreas con nombre en el diseño de cuadrícula
Ahora es más fácil compilar diseños 2D complejos con áreas con nombre en el @Experimental Grid componente. En lugar de administrar índices numéricos de columnas y filas en los elementos, puedes definir regiones semánticas en tu GridConfigurationScope y posicionar elementos componibles por nombre de área.
@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")) } }
Para obtener más información, consulta la documentación.
Rendimiento
Al igual que con cada versión, seguimos invirtiendo en el rendimiento de Compose para garantizar que el framework te ayude a compilar apps atractivas y de alto rendimiento. En esta versión, nos enfocamos en mejorar el rendimiento de inicio y ahora vemos el tiempo hasta la visualización inicial (el tiempo que tarda una app en producir su primer fotograma) que es comparable a Views en nuestros benchmarks.
Actualizaciones de pruebas y herramientas
Sincronización de pruebas
Compose 1.12 presenta nuevas APIs de prueba diseñadas para reducir los tiempos de ejecución de pruebas y eliminar la inestabilidad durante el muestreo de estado:
hasPendingWork: Verifica de forma pasiva si la IU tiene trabajo pendiente sin avanzar el reloj, lo que es ideal para los bucles de animación manuales.runWithoutImplicitWait: Inhabilita temporalmente la sincronización implícita cuando se pasa por los fotogramas del reloj manual (p.ej., pruebas de animación).
@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) } } } }
Otros cambios destacados:
- La API de
captureToImageahora te permite capturar una ventana emergente o un diálogo junto con su ancla en un solo mapa de bits. - Se agregó
onRootWithViewInteractionpara limitar las búsquedas semánticas de Compose a vistas de Android específicas. Esto simplifica las pruebas de IUs híbridas, comoRecyclerViews, sin requerir etiquetas de prueba únicas en el código de producción. @PreviewWrapperanotaciones ahora se pueden aplicar a clases@MultiPreviewpersonalizadas, lo que permite configuraciones de vista previa reutilizables (como temas personalizados) en varios componentes.
¡Feliz compilación!
Compose 1.12 hace que el desarrollo de apps sea más fácil y expresivo que nunca, con gradientes de malla, compatibilidad con una amplia gama de colores, fuentes variables descargables, integración de Credential Manager y herramientas de prueba más rápidas. Como siempre, valoramos tus comentarios, así que comparte tus opiniones sobre estos cambios o lo que te gustaría ver a continuación en nuestro seguimiento de errores. ¡Feliz compilación!
-
Novedades sobre productosCon la introducción del Pixel 11 Pro Fold, el Pixel Watch 5 y toda la familia Pixel, los usuarios se mueven sin problemas en diversos tamaños de pantalla, posturas únicas y experiencias inteligentes.
-
Novedades sobre productosHoy, celebramos oficialmente cinco años desde el lanzamiento de Jetpack Compose 1.0. Desde la versión 1.0, anunciada el 28 de julio de 2021, hasta nuestra versión 1.11 más reciente, vimos que las APIs evolucionaron significativamente a lo largo de los años, y nos tomamos un momento para celebrarlo.
Rebecca Franks, Nick Butcher, Loryn Hairston • Lectura de 4 min -
Novedades sobre productosEn los casi 5 años desde que se lanzó Jetpack Compose, invertimos en ofrecerte todas las funciones, el rendimiento y las herramientas que necesitas para compilar IUs increíbles en la variedad de dispositivos Android.
Nick Butcher • Lectura de 2 min
Recibe la información más reciente sobre el desarrollo de Android en tu bandeja de entrada todas las semanas.