Novità sul prodotto

Novità della release di agosto 2026 di Jetpack Compose

Lettura di 5 minuti
Visualizza il profilo di Nick Butcher
Nick Butcher Product Manager

Oggi, la release di agosto 2026 di Jetpack Compose è stabile. Questa release introduce la versione 1.12 nei moduli principali di Compose (vedi la mappatura completa del BOM), introducendo API visive avanzate come Mesh Gradients e il supporto per la gamma di colori ampia (WCG), funzionalità di layout strutturale come le aree denominate in Grid, l'integrazione perfetta con Credential Manager di Android e miglioramenti significativi in termini di test e prestazioni.

Per aggiornare il tuo progetto alla release di oggi, esegui l'upgrade della versione del BOM di Compose2026.08.00:

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

Modifiche che causano interruzioni

  • AGP e SDK di compilazione: Compose 1.12 aggiorna compileSdk all'API 37, richiedendo un AGP minimo 9.1.2. Ti ricordiamo che Compose avrà sempre come target l'ultima versione di compileSdk. Scopri di più su questa modifica qui.
  • Modifier.onFirstVisible() è obsoleta: esegui la migrazione a Modifier.onVisibilityChanged(), che fornisce un monitoraggio più preciso della soglia di visibilità.

Grafica

Mesh Gradients

Compose 1.12 introduce MeshGradientPainter per aiutarti a creare gradienti di colore organici a più punti.

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)
)

Per ulteriori informazioni ed esempi, consulta la documentazione.

Supporto per la gamma di colori ampia e l'HDR

I display moderni offrono una fedeltà dei colori estesa e una gamma dinamica più elevata. In Compose 1.12, è stato abilitato il supporto completo della pipeline per la gamma di colori ampia (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 mantenuti fino al rendering della piattaforma senza il blocco dei colori. 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 a GraphicsLayer e Modifier.graphicsLayer, che puoi utilizzare per aumentare i limiti visivi del livello oltre le dimensioni misurate. Applica LayerOutsets per evitare il comportamento clipToBounds implicito quando il livello viene promosso a un buffer fuori schermo.

Stili

In occasione di Google I/O, abbiamo condiviso la nostra visione iniziale dell'API Styles di Compose, un modo unificato e performante per applicare lo stile 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 che questo livello fondamentale sia corretto, l'API rimarrà sperimentale e potresti riscontrare modifiche che causano interruzioni. 

Ottimizzazioni di runtime

Sovraccarico SideEffect con chiave

SideEffect ora supporta gli argomenti chiave, che ti consentono di attivare effetti collaterali una tantum ogni volta che cambiano chiavi specifiche. Questo può portare a prestazioni migliori rispetto all'utilizzo di LaunchedEffect o DisposableEffect quando non hai bisogno della coroutine o del blocco di eliminazione. SideEffect è fino al 90% più veloce di LaunchedEffect e circa il 20% più veloce di DisposableEffect. Tieni presente che SideEffect esegue il suo 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 l'avvio dopo il completamento del frame corrente. 

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

Animazione

Transizioni interattive a due fasi

  • Nuovi composableDeferredAnimatedContentDeferredAnimatedVisibility consentono di creare transizioni a due fasi, ad es. 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) possono ora essere manipulate manualmente in tempo reale (ad es. monitorando 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 per gli elementi condivisi: un nuovo flag permitTransformDuringDeferredTransition in SharedContentConfig controlla 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 su gesti viene trasferita a un'animazione attivata:

colorCards.gif

Testo, input e integrazioni della piattaforma

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 dei caratteri e dei paragrafi in linea utilizzando SpanStyleParagraphStyle 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()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 durante 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 SelectionState API fornisce il controllo programmatico e l'osservabilità della selezione del testo all'interno di un SelectionContainer. L'hosting di un oggetto SelectionState tramite rememberSelectionState() e il passaggio a SelectionContainer espone selectedTexts come un 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 tra i 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 Compose ora si integrano in modo nativo con Credential Manager di Android (API 34 e versioni successive) tramite il framework di compilazione automatica (le versioni precedenti all'API 34 sono gestite da androidx.credentials library). Collegando 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 per le impostazioni delle varianti dei caratteri nei caratteri scaricabili.
  • È stato attivato lo scorrimento automatico quando si trascina la selezione del testo oltre la finestra di visualizzazione in SelectionContainer.
  • È stato aggiunto il supporto per i suoni di interazione automatica (clic e navigazione con il focus) ai componenti di Compose, con un nuovo SoundEffectOnInteraction composable per consentire l'esclusione esplicita. Tieni presente che, di conseguenza, ora i listener di clic semantici devono essere chiamati dal thread principale, il che potrebbe influire su un piccolo numero di casi di test.
  • KeyboardType ora include DateTimeDateTime, e SignedDecimal.
  • BasicSecureTextField ora utilizza TextObfuscationMode.System per impostazione predefinita, mentre RevealLastTyped funge da override assoluto.

Miglioramenti del layout

Aree denominate nel layout a griglia

La creazione di layout 2D complessi è ora più semplice con le aree denominate nel componente @Experimental Grid. Anziché gestire gli indici numerici di colonne e righe tra gli elementi, puoi definire regioni semantiche in GridConfigurationScope e posizionare i composable 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 ulteriori informazioni, 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 stiamo riscontrando un Time to Initial Display (il tempo necessario a un'app per produrre il primo frame) paragonabile a Views nei nostri benchmark.

timetoinitialdisplay@2x _v2.png

Upgrade di test e strumenti

Sincronizzazione dei test

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 un lavoro in attesa senza avanzare l'orologio, ideale per i loop di animazione manuali.
  • runWithoutImplicitWait: disabilita temporaneamente la sincronizzazione implicita quando si scorrono i frame 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 captureToImage ora ti consente di acquisire un popup o una finestra di dialogo insieme al relativo ancoraggio in una singola bitmap.
  • È stato aggiunto onRootWithViewInteraction per limitare le ricerche semantiche di Compose a View Android specifiche. Questo semplifica il test delle UI ibride, come RecyclerViews, senza richiedere tag di test univoci nel codice di produzione.
  • @PreviewWrapper annotazioni ora possono essere applicate alle classi @MultiPreview personalizzate, consentendo configurazioni di anteprima riutilizzabili (come i temi personalizzati) in più componenti.

Buona composizione

Compose 1.12 semplifica e rende più espressivo che mai lo sviluppo di app, con gradienti mesh, supporto per la gamma di colori ampia, caratteri variabili scaricabili, integrazione di Gestore delle credenziali e strumenti di test più veloci. Come sempre, apprezziamo il tuo contributo, quindi condividi il tuo feedback su queste modifiche o su ciò che ti piacerebbe vedere in futuro nel nostro strumento di monitoraggio dei problemi. Buona composizione!

Continua a leggere