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 todos los módulos principales de Compose (consulta la asignación completa del BOM), que introduce APIs visuales enriquecidas, como la compatibilidad con degradados de malla y la amplia gama de colores (WCG), funciones de diseño estructural, como las áreas con nombre en Grid, integración fluida con el Administrador de credenciales 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 tu BOM de Compose a 2026.08.00:
implementation(platform("androidx.compose:compose-bom:2026.08.00"))
Cambios rotundos
- AGP y Compile SDK: Compose 1.12 actualiza compileSdk a la API 37, lo que requiere un AGP 9.1.2 como mínimo. Como recordatorio, Compose siempre tendrá como objetivo el compileSdk más reciente. Obtén más información sobre este cambio aquí.
Modifier.onFirstVisible()dejó de estar disponible: Migra a Modifier.onVisibilityChanged(), que proporciona un seguimiento más preciso del umbral de visibilidad.
Gráficos
Gradientes de malla
Compose 1.12 presenta MeshGradientPainter para ayudarte a crear degradados 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.
Amplia gama de colores y compatibilidad con HDR
Las pantallas modernas ofrecen una mayor fidelidad del color y un rango dinámico más alto. En Compose 1.12, se habilitó la compatibilidad completa con la canalización para la amplia gama de colores (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 fijación de color. Los colores volverán a sRGB de forma segura si usan un espacio de color no compatible (p. ej., CieXyz, CieLab o Oklab), si 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 notables:
- Se agregó
LayerOutsetsaGraphicsLayeryModifier.graphicsLayer, que puedes usar para aumentar los límites visuales de la capa más allá de su tamaño medido. AplicaLayerOutsetspara evitar el comportamiento implícito declipToBoundscuando la capa se promueve a un búfer fuera de pantalla.
Estilos
En Google I/O, compartimos nuestra visión inicial de la API de Styles de Compose, una forma unificada y eficiente de diseñar componentes. Desde entonces, seguimos desarrollando la arquitectura subyacente para garantizar una seguridad de tipos estricta y una corrección predecible, y para admitir la creación de sistemas de diseño personalizados.
Para asegurarnos de que esta capa fundamental sea correcta, la API seguirá siendo experimental y es posible que se produzcan cambios que interrumpan su funcionamiento.
Optimizaciones de tiempo de ejecución
Sobrecarga de SideEffect con clave
SideEffect ahora admite argumentos de 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 o el bloque de descarte. 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 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
DeferredTargetAnimationya no se encuentra en estado experimental.
Transiciones interactivas de dos etapas
- Nuevos elementos componibles:
DeferredAnimatedContentyDeferredAnimatedVisibilitypermiten crear transiciones agradables de dos etapas, p.ej., para el seguimiento del gesto atrás predictivo. - 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., para hacer un 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 marca
permitTransformDuringDeferredTransitionenSharedContentConfigcontrola si los elementos compartidos se transforman visualmente junto con sus contenedores principales 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 muestran dos demostraciones de casos de uso en los que una animación controlada por gestos se transfiere a una animación activada:
Integraciones de texto, entrada y plataformas
Formato de texto editable
Las nuevas APIs ofrecen formato de texto enriquecido para el 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 de TextFieldBuffer (como dentro de textFieldState.edit { ... } o un InputTransformation). Además, TextFieldBuffer proporciona las APIs de getSpanStyles() y getParagraphStyles() que devuelven objetos de TrackedRange, lo que te permite leer, actualizar o quitar los estilos aplicados. Para complementar la creación de formato, TextFieldState ahora expone una propiedad textStyles de solo lectura para consultar los estilos activos en los rangos, mientras que TextFieldBuffer proporciona originalTextStyles para inspeccionar el estado del 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 API de SelectionState proporciona control y observabilidad programáticos sobre la selección de texto dentro de un SelectionContainer. Elevar un objeto SelectionState a través de rememberSelectionState() y pasarlo a SelectionContainer expone selectedTexts como una lista reactiva de AnnotatedStrings y proporciona 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 y versiones posteriores) a través del framework de Autocompletar (las versiones anteriores a la API 34 se controlan con androidx.credentials library). Si adjuntas 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 notables:
- Se agregó compatibilidad con la configuración de variantes de fuentes en fuentes descargables.
- Se habilitó el desplazamiento automático cuando se arrastra la selección de texto más allá del viewport en
SelectionContainer. - Se agregó compatibilidad con sonidos de interacción automáticos (clics y navegación por enfoque) a los componentes de Compose, con un nuevo elemento
SoundEffectOnInteractioncomponible 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,DateTimeySignedDecimal.BasicSecureTextFieldahora usaTextObfuscationMode.Systemde forma predeterminada, mientras queRevealLastTypedfunciona como una anulación absoluta.
Mejoras en el diseño
Áreas con nombre en el diseño de cuadrícula
Ahora es más fácil crear diseños complejos en 2D con áreas con nombre en el componente @Experimental Grid. En lugar de administrar índices numéricos de columnas y filas en todos 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 eficientes. En esta versión, nos enfocamos en mejorar el rendimiento del inicio y ahora vemos que el tiempo hasta la visualización inicial (el tiempo que tarda una app en producir su primer fotograma) es comparable al de Views en nuestras comparaciones.
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 las pruebas y eliminar la inestabilidad durante el muestreo de estados:
hasPendingWork: Comprueba de forma pasiva si la IU tiene trabajo pendiente sin adelantar el reloj, lo que es ideal para los bucles de animación manual.runWithoutImplicitWait: Inhabilita temporalmente la sincronización implícita cuando se avanza 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 notables:
- 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 el alcance de las búsquedas semánticas de Compose a Views de Android específicas. Esto simplifica las pruebas de IU híbridas, comoRecyclerViews, sin requerir etiquetas de prueba únicas en el código de producción. - Ahora se pueden aplicar anotaciones
@PreviewWrappera clases@MultiPreviewpersonalizadas, lo que permite configuraciones de vista previa reutilizables (como temas personalizados) en varios componentes.
¡Feliz composición!
Compose 1.12 facilita y hace más expresivo que nunca el desarrollo de apps, con degradados de malla, compatibilidad con una amplia gama de colores, fuentes variables descargables, integración del Administrador de credenciales y herramientas de prueba más rápidas. Como siempre, valoramos tus comentarios, así que no dudes en compartir tus opiniones sobre estos cambios o lo que te gustaría ver a continuación en nuestro rastreador de problemas. ¡Feliz composición!
-
Novedades del productoGooglebook presenta una nueva categoría de laptops creadas sobre una base compartida de Android. El hardware de alto rendimiento de socios como HP, Dell, Lenovo, Acer y Asus combina la comodidad de los dispositivos móviles con la potencia de las computadoras de escritorio.
Fahd Imtiaz, Loryn Hairston • Lectura de 4 min -
Novedades del productoCon la presentación del Pixel 11 Pro Fold, el Pixel Watch 5 y toda la familia Pixel, los usuarios se desplazan sin problemas entre diversos tamaños de pantalla, posturas únicas y experiencias inteligentes.
-
Novedades del productoHoy celebramos oficialmente el quinto aniversario del lanzamiento de Jetpack Compose 1.0. Desde la versión 1.0, anunciada el 28 de julio de 2021, hasta nuestro lanzamiento más reciente de la versión 1.11, 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
Recibe la información más reciente sobre el desarrollo de Android en tu bandeja de entrada todas las semanas.