Eseguire la migrazione da Material 2.5 a Material 3 in Compose per Wear OS

Material 3 Expressive è la nuova evoluzione di Material Design. Include temi, componenti e funzionalità di personalizzazione aggiornati, come il colore dinamico.

Questa guida si concentra sulla migrazione dalla libreria Jetpack Wear Compose Material 2.5 (androidx.wear.compose) alla libreria Jetpack Wear Compose Material 3 (androidx.wear.compose.material3) per le app.

Approcci

Per eseguire la migrazione del codice dell'app da M2.5 a M3, segui lo stesso approccio descritto nella guida alla migrazione di Compose Material per smartphone, in particolare:

Dipendenze

M3 ha un pacchetto e una versione diversi rispetto a M2.5:

M2.5

implementation("androidx.wear.compose:compose-material:1.4.0")

M3

implementation("androidx.wear.compose:compose-material3:1.7.0-alpha01")

Consulta le versioni più recenti di M3 nella pagina delle release di Wear Compose Material 3.

La libreria Wear Compose Foundation versione 1.7.0-alpha01 introduce alcuni nuovi componenti progettati per funzionare con i componenti di Material 3. Allo stesso modo, SwipeDismissableNavHost della libreria Wear Compose Navigation ha un'animazione aggiornata quando viene eseguito su Wear OS 6 (livello API 36) o versioni successive. Quando esegui l'aggiornamento alla versione 3 di Wear Compose Material, ti consigliamo di aggiornare anche le librerie Wear Compose Foundation e Navigation:

implementation("androidx.wear.compose:compose-foundation:1.7.0-alpha01")
implementation("androidx.wear.compose:compose-navigation:1.7.0-alpha01")

Tema

Sia in M2.5 che in M3, il componibile del tema si chiama MaterialTheme, ma i pacchetti di importazione e i parametri sono diversi. In M3, il parametro Colors è stato rinominato in ColorScheme ed è stato introdotto MotionScheme per implementare le transizioni.

M2.5

import androidx.wear.compose.material.MaterialTheme

MaterialTheme(
    colors = AppColors,
    typography = AppTypography,
    shapes = AppShapes,
    content = content
)

M3

import androidx.wear.compose.material3.MaterialTheme
// ...
    MaterialTheme(
        colorScheme = ColorScheme(),
        typography = Typography(),
        shapes = Shapes(),
        motionScheme = MotionScheme.standard(),
        content = { /*content here*/ }
    )

Colore

Il sistema di colori in M3 è notevolmente diverso rispetto a M2.5. Il numero di parametri di colore è aumentato, hanno nomi diversi e vengono mappati ai componenti di M3 in modo differente. In Compose, questo vale per la classe Colors di M2.5, la classe ColorScheme di M3 e le funzioni correlate:

M2.5

import androidx.wear.compose.material.Colors

val appColorScheme: Colors = Colors(
   // M2.5 Color parameters
)

M3

import androidx.wear.compose.material3.ColorScheme
// ...
    val appColorScheme: ColorScheme = ColorScheme(
        // M3 ColorScheme parameters
    )

La seguente tabella descrive le principali differenze tra M2.5 e M3:

M2.5 M3
Color È stato rinominato in ColorScheme
13 colori 28 colori
N/D Nuovi temi cromatici dinamici
N/D Nuovi colori terziari per una maggiore espressività

Temi cromatici dinamici

Una nuova funzionalità di M3 sono i temi cromatici dinamici. Se gli utenti cambiano i colori del quadrante, i colori della UI cambiano di conseguenza.

Utilizza la funzione dynamicColorScheme per implementare la combinazione di colori dinamica e fornisci defaultColorScheme come funzione di riserva nel caso in cui la combinazione di colori dinamica non sia disponibile.

@Composable
fun myApp() {
    val dynamicColorScheme = dynamicColorScheme(LocalContext.current)
    MaterialTheme(colorScheme = dynamicColorScheme ?: myBrandColors) {}
}

internal val myBrandColors: ColorScheme = ColorScheme( /* Specify colors here */)

Tipografia

Il sistema tipografico in M3 è diverso rispetto a M2.5 e include le seguenti funzionalità:

  • Nove nuovi stili di testo
  • Caratteri flessibili, che consentono di personalizzare le scale tipografiche in base a diversi spessori, larghezze e rotondità
  • AnimatedText, che utilizza caratteri flessibili

M2.5

import androidx.wear.compose.material.Typography

val Typography = Typography(
   // M2.5 TextStyle parameters
)

M3

import androidx.wear.compose.material3.Typography

val Typography = Typography(
    // M3 TextStyle parameters
)

Caratteri flessibili

I caratteri flessibili consentono ai designer di specificare la larghezza e lo spessore del carattere per dimensioni specifiche.

Stili di testo

In M3 sono disponibili i seguenti stili di testo, che vengono utilizzati per impostazione predefinita dai vari componenti di M3.

Tipografia TextStyle
Display displayLarge, displayMedium, displaySmall
Titolo titleLarge, titleMedium, titleSmall
Etichetta labelLarge, labelMedium, labelSmall
Corpo bodyLarge, bodyMedium, bodySmall, bodyExtraSmall
Numerale numeralExtraLarge, numeralLarge, numeralMedium, numeralSmall, numeralExtraSmall
Arco arcLarge, arcMedium, arcSmall

Forma

Il sistema di forme in M3 è diverso rispetto a M2.5. Il numero di parametri di forma è aumentato, hanno un nome diverso e vengono mappati ai componenti di M3 in modo differente. Sono disponibili le seguenti dimensioni per le forme:

  • XS
  • S
  • Media
  • L
  • XL

In Compose, questo vale per la classe Shapes di M2 e per la classe Shapes di M3:

M2.5

import androidx.wear.compose.material.Shapes

val Shapes = Shapes(
   // M2.5 Shapes parameters
)

M3

import androidx.wear.compose.material3.Shapes

val Shapes = Shapes(
    // M3 Shapes parameters
)

Utilizza la mappatura dei parametri Shapes da Migrazione da Material 2 a Material 3 in Compose come punto di partenza.

Morphing di forme

M3 introduce il morphing di forme: ora le forme si trasformano in risposta alle interazioni.

Il comportamento di morphing di forme è disponibile come variante di diversi pulsanti rotondi. Vedi il seguente elenco di pulsanti che supportano il morphing di forme:

Pulsanti Funzione di morphing di forme
IconButton IconButtonDefaults.animatedShape anima il pulsante dell'icona quando viene premuto
IconToggleButton IconToggleButtonDefaults.animatedShape anima il pulsante di attivazione/disattivazione dell'icona quando viene premuto e
IconToggleButtonDefaults.variantAnimatedShapes anima il pulsante di attivazione/disattivazione dell'icona quando viene premuto e selezionato/deselezionato
TextButton TextButtonDefaults.animatedShape anima il pulsante di testo quando viene premuto
TextToggleButton TextToggleButtonDefaults.animatedShapes anima il pulsante di attivazione/disattivazione del testo quando viene premuto e TextToggleButtonDefaults.variantAnimatedShapes anima il pulsante di attivazione/disattivazione del testo quando viene premuto e selezionato/deselezionato

Componenti e layout

La maggior parte dei componenti e dei layout di M2.5 è disponibile in M3. Tuttavia, alcuni componenti e layout di M3 non esistono in M2.5. Inoltre, alcuni componenti di M3 hanno più varianti rispetto ai loro equivalenti in M2.5.

Sebbene alcuni componenti richiedano considerazioni speciali, le seguenti mappature delle funzioni sono consigliate come punto di partenza:

Material 2.5 Material 3
androidx.wear.compose.material.dialog.Alert androidx.wear.compose.material3.AlertDialog
androidx.wear.compose.material.Button androidx.wear.compose.material3.IconButton o androidx.wear.compose.material3.TextButton
androidx.wear.compose.material.Card androidx.wear.compose.material3.Card
androidx.wear.compose.material.TitleCard androidx.wear.compose.material3.TitleCard
androidx.wear.compose.material.AppCard androidx.wear.compose.material3.AppCard
androidx.wear.compose.material.Checkbox Nessun equivalente in M3, esegui la migrazione ad androidx.wear.compose.material3.CheckboxButton o androidx.wear.compose.material3.SplitCheckboxButton
androidx.wear.compose.material.Chip androidx.wear.compose.material3.Button o
androidx.wear.compose.material3.OutlinedButton o
androidx.wear.compose.material3.FilledTonalButton o
androidx.wear.compose.material3.ChildButton
androidx.wear.compose.material.CompactChip androidx.wear.compose.material3.CompactButton
androidx.wear.compose.material.InlineSlider androidx.wear.compose.material3.Slider
androidx.wear.compose.material.LocalContentAlpha() È stato rimosso perché non utilizzato da Text o Icon in Material 3
androidx.wear.compose.material.PositionIndicator androidx.wear.compose.material3.ScrollIndicator
androidx.wear.compose.material.RadioButton Nessun equivalente in M3, esegui la migrazione ad androidx.wear.compose.material3.RadioButton o androidx.wear.compose.material3.SplitRadioButton
androidx.wear.compose.material.SwipeToRevealCard androidx.wear.compose.material3.SwipeToReveal
androidx.wear.compose.material.SwipeToRevealChip androidx.wear.compose.material3.SwipeToReveal
android.wear.compose.material.Scaffold androidx.wear.compose.material3.AppScaffold e androidx.wear.compose.material3.ScreenScaffold
androidx.wear.compose.material.SplitToggleChip Nessun equivalente in M3, esegui la migrazione ad androidx.wear.compose.material3.SplitCheckboxButton, androidx.wear.compose.material3.SplitSwitchButton o androidx.wear.compose.material3.SplitRadioButton
androidx.wear.compose.material.Switch Nessun equivalente in M3, esegui la migrazione ad androidx.wear.compose.material3.SwitchButton o androidx.wear.compose.material3.SplitSwitchButton
androidx.wear.compose.material.ToggleButton androidx.wear.compose.material3.IconToggleButton o androidx.wear.compose.material3.TextToggleButton
androidx.wear.compose.material.ToggleChip androidx.wear.compose.material3.CheckboxButton o
androidx.wear.compose.material3.RadioButton o
androidx.wear.compose.material3.SwitchButton
androidx.wear.compose.material.Vignette Rimosso perché non incluso nella progettazione di Material 3 Expressive per Wear OS

Ecco un elenco completo di tutti i componenti Material 3:

Material 3 Componente equivalente di Material 2.5 (se non nuovo in M3)
androidx.wear.compose.material3.AlertDialog androidx.wear.compose.material.dialog.Alert
androidx.wear.compose.material3.AnimatedPage Novità
androidx.wear.compose.material3.AnimatedText Novità
androidx.wear.compose.material3.AppScaffold android.wear.compose.material.Scaffold (con androidx.wear.compose.material3.ScreenScaffold)
androidx.wear.compose.material3.Button androidx.wear.compose.material.Chip
androidx.wear.compose.material3.ButtonGroup Nuovo
androidx.wear.compose.material3.Card androidx.wear.compose.material.Card
androidx.wear.compose.material3.CheckboxButton androidx.wear.compose.material.ToggleChip con un controllo di attivazione/disattivazione della casella di controllo
androidx.wear.compose.material3.ChildButton androidx.wear.compose.material.Chip (solo quando non è richiesto uno sfondo)
androidx.wear.compose.material3.CircularProgressIndicator androidx.wear.compose.material.CircularProgressIndicator
androidx.wear.compose.material3.CompactButton androidx.wear.compose.material.CompactChip
androidx.wear.compose.material3.ConfirmationDialog androidx.wear.compose.material.dialog.Confirmation
androidx.wear.compose.material3.curvedText androidx.wear.compose.material.curvedText
androidx.wear.compose.material3.DatePicker Nuovo
androidx.wear.compose.material3.Dialog androidx.wear.compose.material.dialog.Dialog
androidx.wear.compose.material3.EdgeButton Nuovo
androidx.wear.compose.material3.FadingExpandingLabel Nuovo
androidx.wear.compose.material3.FilledTonalButton androidx.wear.compose.material.Chip quando è richiesto uno sfondo del pulsante tonale
androidx.wear.compose.material3.HorizontalPageIndicator androidx.wear.compose.material.HorizontalPageIndicator
androidx.wear.compose.material3.HorizontalPagerScaffold Nuovo
androidx.wear.compose.material3.Icon androidx.wear.compose.material.Icon
androidx.wear.compose.material3.IconButton androidx.wear.compose.material.Button
androidx.wear.compose.material3.IconToggleButton androidx.wear.compose.material.ToggleButton
androidx.wear.compose.material3.LevelIndicator Nuovo
androidx.wear.compose.material3.LinearProgressIndicator Nuovo
androidx.wear.compose.material3.ListHeader androidx.wear.compose.material.ListHeader
androidx.wear.compose.material3.ListSubHeader Nuovo
androidx.wear.compose.material3.MaterialTheme androidx.wear.compose.material.MaterialTheme
androidx.wear.compose.material3.OpenOnPhoneDialog Nuovo
androidx.wear.compose.material3.Picker androidx.wear.compose.material.Picker
androidx.wear.compose.material3.PickerGroup androidx.wear.compose.material.PickerGroup
androidx.wear.compose.material3.RadioButton androidx.wear.compose.material.ToggleChip con un controllo di attivazione/disattivazione del pulsante di opzione
androidx.wear.compose.material3.ScreenScaffold android.wear.compose.material.Scaffold (con androidx.wear.compose.material3.AppScaffold)
androidx.wear.compose.material3.ScrollIndicator androidx.wear.compose.material.PositionIndicator
androidx.wear.compose.material3.scrollAway androidx.wear.compose.material.scrollAway
androidx.wear.compose.material3.SegmentedCircularProgressIndicator Nuovo
androidx.wear.compose.material3.Slider androidx.wear.compose.material.InlineSlider
androidx.wear.compose.material3.SplitRadioButton androidx.wear.compose.material.SplitToggleChip
androidx.wear.compose.material3.SplitCheckboxButton androidx.wear.compose.material.SplitToggleChip
androidx.wear.compose.material3.SplitSwitchButton androidx.wear.compose.material.SplitToggleChip
androidx.wear.compose.material3.Stepper androidx.wear.compose.material.Stepper
androidx.wear.compose.material3.SwipeToDismissBox androidx.wear.compose.material.SwipeToDismissBox
androidx.wear.compose.material3.SwipeToReveal androidx.wear.compose.material.SwipeToRevealCard e androidx.wear.compose.material.SwipeToRevealChip
androidx.wear.compose.material3.SwitchButton androidx.wear.compose.material.ToggleChip con un controllo di attivazione/disattivazione
androidx.wear.compose.material3.Text androidx.wear.compose.material.Text
androidx.wear.compose.material3.TextButton androidx.wear.compose.material.Button
androidx.wear.compose.material3.TextToggleButton androidx.wear.compose.material.ToggleButton
androidx.wear.compose.material3.TimeText androidx.wear.compose.material.TimeText
androidx.wear.compose.material3.VerticalPagerScaffold Novità

Infine, un elenco di alcuni componenti pertinenti della libreria Wear Compose Foundation:

Wear Compose Foundation 1.7.0-alpha01
androidx.wear.compose.foundation.hierarchicalFocusGroup Utilizzato per annotare i componibili in un'applicazione, per tenere traccia della parte attiva della composizione e coordinare le selezioni.
androidx.wear.compose.foundation.pager.HorizontalPager Un pager a scorrimento orizzontale, basato sui componenti di Compose Foundation con miglioramenti specifici per Wear per migliorare le prestazioni e il rispetto delle linee guida di Wear OS.
androidx.wear.compose.foundation.pager.VerticalPager Un pager a scorrimento verticale, basato sui componenti di Compose Foundation con miglioramenti specifici per Wear per migliorare le prestazioni e il rispetto delle linee guida di Wear OS.
androidx.wear.compose.foundation.lazy.TransformingLazyColumn Può essere utilizzato al posto di ScalingLazyColumn per aggiungere effetti di trasformazione dello scorrimento a ogni elemento.

Pulsanti

I pulsanti in M3 sono diversi da quelli in M2.5. Il componente Chip di M2.5 è stato sostituito da Button. L'implementazione di Button fornisce valori predefiniti per Text maxLines e textAlign. Questi valori predefiniti possono essere sostituiti nell'elemento Text.

M2.5

import androidx.wear.compose.material.Chip

//M2.5 Buttons
Chip(...)
CompactChip(...)
Button(...)

M3

//M3 Buttons
Button(onClick = { }){}
CompactButton(onClick = { }){}
IconButton(onClick = { }){}
TextButton(onClick = { }){}

M3 include anche nuove varianti di pulsanti. Consulta la panoramica del riferimento API di Compose Material 3.

M3 introduce un nuovo pulsante: EdgeButton. EdgeButton è disponibile in 4 dimensioni diverse: XS, S, M e L. L'implementazione di EdgeButton fornisce un valore predefinito per maxLines a seconda delle dimensioni, che può essere personalizzato.

Se utilizzi TransformingLazyColumn o ScalingLazyColumn, passa EdgeButton in ScreenScaffold in modo che si trasformi, cambiando forma con lo scorrimento, anziché aggiungere un EdgeButton come ultimo elemento dell'elenco. Vedi il seguente codice per controllare come utilizzare EdgeButton con ScreenScaffold e TransformingLazyColumn.

val state = rememberTransformingLazyColumnState()
ScreenScaffold(
    scrollState = state,
    contentPadding =
        rememberResponsiveColumnPadding(
            first = ColumnItemType.ListHeader
        ),
    edgeButton = {
        EdgeButton(
            onClick = { }
        ) {
            Text(stringResource(R.string.show))
        }
    }
){ contentPadding ->
    TransformingLazyColumn(state = state, contentPadding = contentPadding,){
        // additional code here
    }
}

Scaffold

Lo scaffold in M3 è diverso rispetto a M2.5. In M3, AppScaffold e il nuovo componibile ScreenScaffold hanno sostituito Scaffold. AppScaffold e ScreenScaffold definiscono la struttura di una schermata e coordinano le transizioni dei componenti ScrollIndicator e TimeText.

AppScaffold consente agli elementi statici della schermata, come TimeText, di rimanere visibili durante le transizioni in-app, ad esempio lo scorrimento per chiudere. ​​Fornisce uno spazio per i contenuti principali dell'applicazione, che di solito vengono forniti da un componente di navigazione come SwipeDismissableNavHost.

Dichiari AppScaffold per un'attività e utilizzi ScreenScaffold per ogni schermata. AppScaffold aggiunge un componente TimeTextpredefinito alle schermate. Puoi ignorarlo se vuoi personalizzarlo utilizzando il parametro timeText.

M2.5

import androidx.wear.compose.material.Scaffold

Scaffold {...}

M3

    AppScaffold {
        val navController = rememberSwipeDismissableNavController()
        SwipeDismissableNavHost(
            navController = navController,
            startDestination = "message_list"
        ) {
            composable("message_list") {
                MessageList(onMessageClick = { id ->
                    navController.navigate("message_detail/$id")
                })
            }
            composable("message_detail/{id}") {
                MessageDetail(id = it.arguments?.getString("id")!!)
            }
        }
    }
}

// Implementation of one of the screens in the navigation
@Composable
fun MessageDetail(id: String) {
    // .. Screen level content goes here
    val scrollState = rememberTransformingLazyColumnState()

    val padding = rememberResponsiveColumnPadding(
        first = ColumnItemType.BodyText
    )

    ScreenScaffold(
        scrollState = scrollState,
        contentPadding = padding
    ) { scaffoldPaddingValues ->
        // Screen content goes here
        // ...

Se utilizzi un HorizontalPager con HorizontalPagerIndicator, puoi eseguire la migrazione a HorizontalPagerScaffold. HorizontalPagerScaffold si trova all'interno di un AppScaffold. AppScaffold e HorizontalPagerScaffold definiscono la struttura di un pager e coordinano le transizioni dei componenti HorizontalPageIndicator e TimeText.

HorizontalPagerScaffold mostra HorizontalPageIndicator al centro/fine della schermata per impostazione predefinita e coordina la visualizzazione e l'occultamento di TimeText e HorizontalPageIndicator a seconda che venga eseguito il paging di Pager, il che è determinato da PagerState.

È disponibile anche un nuovo componente AnimatedPage, che anima una pagina all'interno di un Pager con un effetto di ridimensionamento e velatura in base alla sua posizione.

AppScaffold {
    val pagerState = rememberPagerState(pageCount = { 10 })
    val columnState = rememberTransformingLazyColumnState()
    val contentPadding = rememberResponsiveColumnPadding(
        first = ColumnItemType.ListHeader,
        last = ColumnItemType.BodyText,
    )
    HorizontalPagerScaffold(pagerState = pagerState) {
        HorizontalPager(
            state = pagerState,
        ) { page ->
            AnimatedPage(pageIndex = page, pagerState = pagerState) {
                ScreenScaffold(
                    scrollState = columnState,
                    contentPadding = contentPadding
                ) { contentPadding ->
                    TransformingLazyColumn(
                        state = columnState,
                        contentPadding = contentPadding
                    ) {
                        item {
                            ListHeader(
                                modifier = Modifier.fillMaxWidth()
                            ) {
                                Text(text = "Pager sample")
                            }
                        }
                        item {
                            if (page == 0) {
                                Text(text = "Page #$page. Swipe right")
                            }
                            else{
                                Text(text = "Page #$page. Swipe left and right")
                            }
                        }
                    }
                }

            }
        }
    }
}

Infine, M3 introduce VerticalPagerScaffold, che segue lo stesso pattern di HorizontalPagerScaffold:

AppScaffold {
    val pagerState = rememberPagerState(pageCount = { 10 })

    VerticalPagerScaffold(pagerState = pagerState) {
        VerticalPager(
            state = pagerState
        ) { page ->
            AnimatedPage(pageIndex = page, pagerState = pagerState) {
                ScreenScaffold {
                    ///…
                }
            }
        }
    }
}

Segnaposto

Sono state apportate alcune modifiche all'API da M2.5 a M3. Placeholder.PlaceholderDefaults ora fornisce due modificatori:

  • Modifier.placeholder, che viene disegnato al posto dei contenuti non ancora caricati.
  • Modifier.placeholderShimmer, che fornisce un effetto luccichio di segnaposto eseguito in un ciclo di animazione durante l'attesa del caricamento dei dati.

Consulta la tabella seguente per ulteriori modifiche apportate al componente Placeholder.

M2.5 M3
PlaceholderState.startPlaceholderAnimation È stato rimosso
PlaceholderState.placeholderProgression È stato rimosso
PlaceholderState.isShowContent È stato rinominato in !PlaceholderState.isVisible
PlaceholderState.isWipeOff È stato rimosso
PlaceholderDefaults.painterWithPlaceholderOverlayBackgroundBrush È stato rimosso
PlaceholderDefaults.placeholderBackgroundBrush È stato rimosso
PlaceholderDefaults.placeholderChipColors È stato rimosso

SwipeDismissableNavHost

SwipeDismissableNavHost fa parte di wear.compose.navigation. Quando questo componente viene utilizzato con M3, MaterialTheme di M3 aggiorna LocalSwipeToDismissBackgroundScrimColor e LocalSwipeToDismissContentScrimColor.

TransformingLazyColumn

TransformingLazyColumn fa parte di wear.compose.lazy.foundation e aggiunge il supporto per le animazioni di ridimensionamento e morphing degli elementi di elenco durante lo scorrimento, migliorando l'esperienza utente. È fortemente consigliato eseguire la migrazione delle app da ScalingLazyColumn a TransformingLazyColumn

Analogamente a ScalingLazyColumn, fornisce rememberTransformingLazyColumnState() per creare TransformingLazyColumnState che viene ricordato in tutte le composizioni.

Per aggiungere animazioni di ridimensionamento e morphing, aggiungi quanto segue a ogni elemento di elenco:

  • Modifier.transformedHeight, che ti consente di calcolare l'altezza trasformata degli elementi utilizzando TransformationSpec; puoi utilizzare rememberTransformationSpec(), a meno che tu non abbia bisogno di ulteriore personalizzazione.
  • SurfaceTransformation

Per verificare che la spaziatura interna sia corretta nella parte superiore e inferiore dell'elenco, utilizza il modificatore minimumVerticalContentPadding.

val columnState = rememberTransformingLazyColumnState()
val transformationSpec = rememberTransformationSpec()
ScreenScaffold(
    scrollState = columnState
) { contentPadding ->
    TransformingLazyColumn(
        state = columnState,
        contentPadding = contentPadding
    ) {
        item {
            ListHeader(
                modifier = Modifier
                    .fillMaxWidth()
                    .transformedHeight(this, transformationSpec)
                    .minimumVerticalContentPadding(ListHeaderDefaults.minimumTopListContentPadding),
                transformation = SurfaceTransformation(transformationSpec)
            ) {
                Text(text = "Header")
            }
        }
        // ... other items
        item {
            Button(
                modifier = Modifier
                    .fillMaxWidth()
                    .transformedHeight(this, transformationSpec)
                    .minimumVerticalContentPadding(ButtonDefaults.minimumVerticalListContentPadding),
                transformation = SurfaceTransformation(transformationSpec),
                onClick = { /* ... */ },
                icon = {
                    Icon(
                        imageVector = Icons.Default.Build,
                        contentDescription = "build",
                    )
                },
            ) {
                Text(
                    text = "Build",
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis,
                )
            }
        }
    }
}

Per scoprire di più sulla migrazione da M2.5 a M3 in Compose, consulta le seguenti risorse aggiuntive.

Campioni

Riferimento API e codice sorgente

Progettazione