Oggi, la release di agosto 2026 di Jetpack Compose è stabile. Questa release introduce la versione 1.12 nei moduli principali di Compose (vedi il mapping della distinta base), introducendo API visive avanzate come le sfumature mesh e il supporto della gamma cromatica estesa (WCG), funzionalità di layout strutturale come le aree denominate in Grid, integrazione perfetta con Gestore delle credenziali di Android e miglioramenti significativi di test e prestazioni.
Per aggiornare il tuo progetto alla release di oggi, esegui l'upgrade della versione della distinta base di Compose alla versione 2026.08.00:
implementation(platform("androidx.compose:compose-bom:2026.08.00"))
Modifiche che provocano errori
- AGP e SDK di compilazione: Compose 1.12 aggiorna compileSdk all'API 37, richiedendo AGP 9.1.2 come minimo. Ti ricordiamo che Compose ha sempre come target l'ultima versione di compileSdk. Scopri di più su questa modifica qui.
Modifier.onFirstVisible()è deprecato: esegui la migrazione a Modifier.onVisibilityChanged(), che fornisce un monitoraggio più preciso della soglia di visibilità.
Grafica
Sfumature mesh
Compose 1.12 introduce MeshGradientPainter per aiutarti a creare sfumature di colore organiche e multipunto.
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) )
Per ulteriori informazioni ed esempi, consulta la documentazione.
Supporto di Wide Color Gamut e HDR
I display moderni offrono una fedeltà del colore estesa e una gamma dinamica più elevata. In Compose 1.12 è stato attivato il supporto completo della pipeline per la gamma cromatica estesa (P3) e il rendering HDR in tutta la grafica, la pittura e gli shader di Compose. I colori definiti in spazi colore non sRGB (come Display P3) vengono conservati fino al rendering della piattaforma senza bloccaggio del colore. I colori torneranno in modo sicuro a sRGB se utilizzano uno spazio colore non supportato (ad es. CieXyz, CieLab o Oklab), si basano su uno spazio colore in una versione di Android non supportata (ad es. Bt2020Hlg su Android 13 e versioni precedenti) o se l'app è in esecuzione su Android 9 (API 28) e versioni precedenti.
Altre modifiche importanti:
LayerOutsetsè stato aggiunto aGraphicsLayereModifier.graphicsLayer, che puoi utilizzare per aumentare i limiti visivi del livello oltre le dimensioni misurate. ApplicaLayerOutsetsper evitare il comportamento implicitoclipToBoundsquando il livello viene promosso a un buffer off-screen.
Stili
In occasione di Google I/O, abbiamo condiviso la nostra prima visione dell'API Styles di Compose, un modo unificato e performante per applicare stili ai componenti. Da allora, abbiamo continuato a sviluppare l'architettura sottostante per garantire una rigorosa sicurezza dei tipi e una correttezza prevedibile, nonché per supportare la creazione di sistemi di progettazione personalizzati.
Per assicurarci di implementare correttamente questo livello di base, l'API rimarrà sperimentale e potresti riscontrare modifiche che causano interruzioni.
Ottimizzazioni di runtime
Keyed SideEffect Overload
SideEffect ora supporta gli argomenti chiave, che ti consentono di attivare effetti collaterali una tantum ogni volta che cambiano chiavi specifiche. Ciò può portare a un rendimento migliore rispetto all'utilizzo di un LaunchedEffect o DisposableEffect quando non hai bisogno della coroutine o del blocco dispose. SideEffect è fino al 90% più veloce di LaunchedEffect e circa il 20% più veloce di DisposableEffect. Tieni presente che SideEffect ha effetto prima di DisposableEffect e LaunchedEffect, quindi fai attenzione se esegui la migrazione degli effetti esistenti a questa API, in particolare per LaunchedEffects che si basano sull'invio per iniziare dopo il completamento del frame corrente.
@Composable fun AnalyticsTracker(userId: String, screenName: String) { SideEffect(key1 = userId, key2 = screenName) { analytics.logScreenView(userId, screenName) } }
Animazione
DeferredTargetAnimationnon è più in fase sperimentale.
Transizioni interattive in due fasi
- Nuovi composable:
DeferredAnimatedContenteDeferredAnimatedVisibilityconsentono di creare transizioni in due fasi piacevoli, ad esempio per il monitoraggio del gesto Indietro predittivo. - Controllo manuale dell'animazione: durante la fase posticipata di una transizione, le proprietà animate (come la scala o l'offset) ora possono essere manipolate manualmente in tempo reale (ad es. tracciando un gesto di scorrimento).
- Trasferimento senza interruzioni: al termine della fase posticipata, il motore di transizione prende il controllo ed esegue un trasferimento senza interruzioni, incluso il trasferimento della velocità, alla transizione automatica.
- Supporto degli elementi condivisi: un nuovo flag
permitTransformDuringDeferredTransitioninSharedContentConfigcontrolla se gli elementi condivisi si trasformano visivamente insieme ai relativi contenitori principali durante la fase di transizione posticipata.
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) }
Di seguito sono riportate due demo di casi d'uso in cui un'animazione basata sui gesti viene trasferita a un'animazione attivata:
Integrazioni di testo, input e piattaforme
Formattazione del testo modificabile
Le nuove API offrono la formattazione RTF per il testo modificabile in BasicTextField. Ora puoi applicare e manipolare in modo programmatico la formattazione di caratteri e paragrafi in linea utilizzando SpanStyle e ParagraphStyle tramite il nuovo metodo addStyle() all'interno di un ambito TextFieldBuffer (ad esempio all'interno di textFieldState.edit { ... } o di un InputTransformation). Inoltre, TextFieldBuffer fornisce le API getSpanStyles() e getParagraphStyles() che restituiscono oggetti TrackedRange, consentendoti di leggere, aggiornare o rimuovere gli stili applicati. Per completare la creazione della formattazione, TextFieldState ora espone una proprietà textStyles di sola lettura per eseguire query sugli stili attivi negli intervalli, mentre TextFieldBuffer fornisce originalTextStyles per esaminare lo stato della formattazione prima di una modifica. La formattazione del testo e le annotazioni personalizzate vengono mantenute anche dopo le modifiche alla configurazione.
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
Selezione del testo
Una nuova API SelectionState fornisce controllo e osservabilità programmatici sulla selezione del testo all'interno di un SelectionContainer. L'innalzamento di un oggetto SelectionState tramite rememberSelectionState() e il passaggio a SelectionContainer espone selectedTexts come elenco reattivo di AnnotatedStrings e fornisce metodi come selectAll(), clear(), select(TextRange) e extendSelectionByWord().
Inoltre, utilizza getSelectableTexts() per recuperare tutti gli elementi di testo selezionabili in ordine di layout e selezionare il testo nei composable in SelectionContainer utilizzando un intervallo 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.") } } }
Integrazione di Gestore delle credenziali
I campi di testo di composizione ora si integrano in modo nativo con Credential Manager di Android (API 34+) tramite il framework di compilazione automatica (le versioni precedenti all'API 34 sono gestite da androidx.credentials library). Se si allega la nuova proprietà semantica credentialRequest con CredentialRequestData, gli input di testo possono richiedere passkey, credenziali salvate o richieste di accesso direttamente nel flusso di input dell'utente.
@Composable fun LoginField(textFieldState: TextFieldState) { val credentialData = remember { CredentialRequestData( // Specify Credential Manager request options ) } BasicTextField( state = textFieldState, modifier = Modifier.semantics { credentialRequest = credentialData } ) }
Altre modifiche importanti:
- Supporto delle impostazioni di variazione dei caratteri nei caratteri scaricabili.
- È stato attivato lo scorrimento automatico quando si trascina la selezione di testo oltre la finestra in
SelectionContainer. - È stato aggiunto il supporto per i suoni di interazione automatici (clic e navigazione con messa a fuoco) ai componenti Compose, con un nuovo composable
SoundEffectOnInteractionper consentire l'opt-out. Tieni presente che, in seguito a questa modifica, i listener di clic semantici devono ora essere chiamati dal thread principale, il che potrebbe influire su un numero ridotto di scenari di test. KeyboardTypeora includeDate,Time,DateTimeeSignedDecimal.BasicSecureTextFieldora utilizzaTextObfuscationMode.Systemper impostazione predefinita, mentreRevealLastTypedfunge da override assoluto.
Miglioramenti del layout
Aree denominate nel layout a griglia
Creare layout 2D complessi è ora più facile con le aree denominate nel componente @Experimental Griglia. Anziché gestire gli indici numerici di colonne e righe tra gli elementi, puoi definire regioni semantiche nel tuo GridConfigurationScope e posizionare i componenti componibili in base al nome dell'area.
@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")) } }
Per saperne di più, consulta la documentazione.
Prestazioni
Come per ogni release, continuiamo a investire nelle prestazioni di Compose per garantire che il framework ti aiuti a creare app belle e performanti. In questa release ci siamo concentrati sul miglioramento delle prestazioni di avvio e ora osserviamo un tempo al primo display (il tempo necessario a un'app per produrre il primo frame) paragonabile a Views nei nostri benchmark.
Aggiornamenti di test e strumenti
Test di sincronizzazione
Compose 1.12 introduce nuove API di test progettate per ridurre i tempi di esecuzione dei test ed eliminare l'instabilità durante il campionamento dello stato:
hasPendingWork: controlla passivamente se la UI ha lavoro in sospeso senza far avanzare l'orologio, il che è ideale per i loop di animazione manuali.runWithoutImplicitWait: disattiva temporaneamente la sincronizzazione implicita durante l'avanzamento dei fotogrammi dell'orologio manuale (ad es. test di animazione).
@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) } } } }
Altre modifiche importanti:
- L'API
captureToImageora ti consente di acquisire un popup o una finestra di dialogo insieme al relativo ancoraggio in una singola bitmap. - È stato aggiunto
onRootWithViewInteractionper limitare le ricerche semantiche di Compose a visualizzazioni Android specifiche. Ciò semplifica il test delle UI ibride, comeRecyclerViews, senza richiedere tag di test univoci nel codice di produzione. - Ora le annotazioni
@PreviewWrapperpossono essere applicate alle classi@MultiPreviewpersonalizzate, consentendo configurazioni di anteprima riutilizzabili (come i temi personalizzati) in più componenti.
Buona composizione!
Compose 1.12 rende lo sviluppo di app più semplice ed espressivo che mai, con sfumature mesh, supporto della gamma cromatica ampia, caratteri variabili scaricabili, integrazione di Gestore delle credenziali e strumenti di test più veloci. Come sempre, il tuo contributo è prezioso, quindi condividi il tuo feedback su queste modifiche o su cosa vorresti vedere in futuro nel nostro strumento di monitoraggio dei problemi. Buona composizione!
-
Notizie sui prodottiGooglebook introduce una nuova categoria di laptop basati su una base Android condivisa. L'hardware ad alte prestazioni di partner come HP, Dell, Lenovo, Acer e Asus combina la praticità del mobile con la potenza del desktop.
Fahd Imtiaz, Loryn Hairston • Tempo di lettura: 4 minuti -
Notizie sui prodottiCon l'introduzione di Pixel 11 Pro Fold, Pixel Watch 5 e l'intera famiglia Pixel, gli utenti passano senza problemi da schermi di dimensioni diverse, posture uniche ed esperienze intelligenti.
Fahd Imtiaz, Loryn Hairston, Tracy Agyemang • Tempo di lettura: 4 minuti -
Notizie sui prodottiOggi celebriamo ufficialmente i cinque anni dal rilascio di Jetpack Compose 1.0. Dalla versione 1.0, annunciata il 28 luglio 2021, alla nostra ultima versione 1.11, abbiamo assistito a una notevole evoluzione delle API nel corso degli anni e ci prendiamo un momento per festeggiare.
Rebecca Franks, Nick Butcher, Loryn Hairston • Tempo di lettura: 4 minuti
Ricevi gli ultimi approfondimenti sullo sviluppo per Android direttamente nella tua casella di posta ogni settimana.