Eseguire la migrazione dal Materiale 2 al Materiale 3 in Compose

Material Design 3 è la prossima evoluzione di Material Design. Include funzionalità aggiornate per temi, componenti e personalizzazione di Material You, come il colore dinamico. È un aggiornamento di Material Design 2 ed è coerente con il nuovo stile visivo e la nuova UI di sistema su Android 12 e versioni successive.

Questa guida è incentrata sulla migrazione dalla libreria Jetpack Compose Material (androidx.compose.material) alla libreria Compose Material 3 (androidx.compose.material3) Jetpack.

Approcci

In generale, non è consigliabile utilizzare sia M2 sia M3 in un'unica app a lungo termine. Ciò è dovuto al fatto che i due sistemi di progettazione e le rispettive librerie differiscono notevolmente in termini di design UX/UI e implementazioni di Compose.

La tua app potrebbe utilizzare un sistema di progettazione, ad esempio quello creato utilizzando Figma. In questi casi, ti consigliamo vivamente di eseguire la migrazione da M2 a M3 da parte tua o del tuo team di progettazione prima di avviare la migrazione di Compose. Non ha senso migrare un'app a M3 se la sua UX/UI è basata su M2.

Inoltre, il tuo approccio alla migrazione dovrebbe variare a seconda delle dimensioni, della complessità e della progettazione UX/UI dell'app. In questo modo puoi ridurre al minimo l'impatto sul codebase. Dovresti adottare un approccio graduale alla migrazione.

Quando eseguire la migrazione

La migrazione deve essere avviata il prima possibile. Tuttavia, è importante valutare se la tua app si trova in una posizione realistica per eseguire completamente la migrazione dalla versione M2 alla versione M3. Prima di iniziare, esistono alcuni scenari di "blocco" da valutare prima di iniziare:

Scenario Approccio consigliato
Nessun "blocco" Avvia migrazione a fasi
Un componente di M2 non è ancora disponibile in M3. Consulta la sezione Componenti e layout di seguito. Avvia migrazione a fasi
Tu o il tuo team di progettazione non avete eseguito la migrazione del sistema di progettazione dell'app da M2 a M3. Esegui la migrazione del sistema di progettazione da M2 a M3, quindi avvia la migrazione in fasi

Anche se rientri negli scenari precedenti, devi adottare un approccio alla migrazione graduale prima di eseguire il commit e il rilascio di un aggiornamento dell'app. In questi casi, utilizzerai M2 e M3 affiancati ed eliminerai gradualmente M2 durante la migrazione a M3.

Approccio per fasi

Di seguito sono riportati i passaggi generali di una migrazione graduale:

  1. Aggiungi la dipendenza M3 insieme a quella M2.
  2. Aggiungi le versioni M3 dei temi della tua app insieme alle versioni M2 dei temi dell'app.
  3. Esegui la migrazione di singoli moduli, schermate o componibili a M3, a seconda delle dimensioni e della complessità della tua app (vedi le sezioni di seguito per i dettagli).
  4. Al termine della migrazione, rimuovi le versioni M2 dei temi dell'app.
  5. Rimuovi la dipendenza M2.

Dipendenze

M3 ha un pacchetto e una versione separati da M2:

M2

implementation "androidx.compose.material:material:$m2-version"

M3

implementation "androidx.compose.material3:material3:$m3-version"

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

Altre dipendenze Material al di fuori delle librerie M2 e M3 principali non sono cambiate. Utilizzano una combinazione dei pacchetti e delle versioni M2 e M3, ma questo non ha alcun impatto sulla migrazione. Possono essere utilizzati così come sono con M3:

Raccolta Pacchetto e versione
Icone del materiale di Scrivi androidx.compose.material:material-icons-*:$m2-version
Crea onde del materiale androidx.compose.material:material-ripple:$m2-version
Classe di dimensioni della finestra del materiale 3 per scrivere androidx.compose.material3:material3-window-size-class:$m3-version

API sperimentali

Alcune API M3 sono considerate sperimentali. In questi casi, devi eseguire l'attivazione a livello di funzione o di file utilizzando l'annotazione ExperimentalMaterial3Api:

import androidx.compose.material3.ExperimentalMaterial3Api

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AppComposable() {
    // M3 composables
}

Applicazione tema

Sia in M2 che in M3, il tema componibile è denominato MaterialTheme, ma i pacchetti e i parametri di importazione sono diversi:

M2

import androidx.compose.material.MaterialTheme

MaterialTheme(
    colors = AppColors,
    typography = AppTypography,
    shapes = AppShapes
) {
    // M2 content
}

M3

import androidx.compose.material3.MaterialTheme

MaterialTheme(
    colorScheme = AppColorScheme,
    typography = AppTypography,
    shapes = AppShapes
) {
    // M3 content
}

Colore

Confronto tra i sistemi di colore M2 e M3
Figura 1. Sistema di colori M2 (sinistra) e sistema di colori M3 (destra).

Il sistema di colori di M3 è notevolmente diverso da quello di M2. Il numero di parametri di colore è aumentato, hanno nomi diversi e sono mappati in modo diverso ai componenti M3. In Compose, questo si applica alla classe M2 Colors, alla classe M3 ColorScheme e alle funzioni correlate:

M2

import androidx.compose.material.lightColors
import androidx.compose.material.darkColors

val AppLightColors = lightColors(
    // M2 light Color parameters
)
val AppDarkColors = darkColors(
    // M2 dark Color parameters
)
val AppColors = if (darkTheme) {
    AppDarkColors
} else {
    AppLightColors
}

M3

import androidx.compose.material3.lightColorScheme
import androidx.compose.material3.darkColorScheme

val AppLightColorScheme = lightColorScheme(
    // M3 light Color parameters
)
val AppDarkColorScheme = darkColorScheme(
    // M3 dark Color parameters
)
val AppColorScheme = if (darkTheme) {
    AppDarkColorScheme
} else {
    AppLightColorScheme
}

Considerate le differenze significative tra i sistemi di colori M2 e M3, non esiste una mappatura ragionevole per i parametri Color. Utilizza invece lo strumento Builder di temi di materiali per generare una combinazione di colori M3. Utilizza i colori M2 come colori di origine "principali" nello strumento, che lo strumento espande nelle tavolozze tonali utilizzate dalla combinazione di colori M3. Le seguenti mappature sono consigliate come punto di partenza:

M2 Builder di temi Material
primary Principale
primaryVariant Secondario
secondary Terziario
surface o background Neutra
Colori M2 utilizzati in Material Theme Builder per generare una combinazione di colori M3
Figura 2. Colori M2 di Jetchat utilizzati in Material Theme Builder per generare una combinazione di colori M3.

Puoi copiare i valori del codice esadecimale del colore per i temi chiaro e scuro dallo strumento e utilizzarli per implementare un'istanza ColorScheme M3. In alternativa, Material Theme Builder può esportare il codice di Compose.

isLight

A differenza della classe Colors M2, la classe ColorScheme M3 non include un parametro isLight. In generale, dovresti provare a creare un modello a livello di tema in base a queste informazioni. Ecco alcuni esempi:

M2

import androidx.compose.material.lightColors
import androidx.compose.material.darkColors
import androidx.compose.material.MaterialTheme

@Composable
private fun AppTheme(
  darkTheme: Boolean = isSystemInDarkTheme(),
  content: @Composable () -> Unit
) {
  val colors = if (darkTheme) darkColors(…) else lightColors(…)
  MaterialTheme(
      colors = colors,
      content = content
  )
}

@Composable
fun AppComposable() {
    AppTheme {
        val cardElevation = if (MaterialTheme.colors.isLight) 0.dp else 4.dp
        …
    }
}

M3

import androidx.compose.material3.lightColorScheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.MaterialTheme

val LocalCardElevation = staticCompositionLocalOf { Dp.Unspecified }
@Composable
private fun AppTheme(
   darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable () -> Unit
) {
   val cardElevation = if (darkTheme) 4.dp else 0.dp
    CompositionLocalProvider(LocalCardElevation provides cardElevation) {
        val colorScheme = if (darkTheme) darkColorScheme(…) else lightColorScheme(…)
        MaterialTheme(
            colorScheme = colorScheme,
            content = content
        )
    }
}

@Composable
fun AppComposable() {
    AppTheme {
        val cardElevation = LocalCardElevation.current
        …
    }
}

Per ulteriori informazioni, consulta Sistemi di progettazione personalizzata nella guida di Scrivi.

Colore dinamico

Una nuova funzionalità in M3 è il colore dinamico. Anziché utilizzare colori personalizzati, un ColorScheme M3 può utilizzare i colori di sfondo del dispositivo su Android 12 e versioni successive, utilizzando le seguenti funzioni:

Tipografia

Confronto tra i sistemi tipografici M2 e M3
Figura 3. Sistema tipografico M3 (sinistra) e sistema tipografico M2 (destra)

Il sistema tipografico in M3 è diverso da quello in M2. Il numero di parametri tipografici è più o meno lo stesso, ma hanno nomi diversi e si mappano in modo diverso ai componenti M3. In Compose, questo si applica alla classe M2 Typography e alla classe M3 Typography:

M2

import androidx.compose.material.Typography

val AppTypography = Typography(
    // M2 TextStyle parameters
)

M3

import androidx.compose.material3.Typography

val AppTypography = Typography(
    // M3 TextStyle parameters
)

Le seguenti mappature dei parametri TextStyle sono consigliate come punto di partenza:

M2 M3
h1 displayLarge
h2 displayMedium
h3 displaySmall
N/A headlineLarge
h4 headlineMedium
h5 headlineSmall
h6 titleLarge
subtitle1 titleMedium
subtitle2 titleSmall
body1 bodyLarge
body2 bodyMedium
caption bodySmall
button labelLarge
N/A labelMedium
overline labelSmall

Forma

Confronto tra i sistemi di forma M2 e M3
Figura 4. Sistema di forma M2 (sinistra) e sistema di forma M3 (destra)

Il sistema di forme in M3 è diverso da quello di M2. Il numero di parametri di forma è aumentato, hanno un nome diverso e si mappano in modo diverso ai componenti M3. In Compose, questo si applica alla classe M2 Shapes e alla classe M3 Shapes:

M2

import androidx.compose.material.Shapes

val AppShapes = Shapes(
    // M2 Shape parameters
)

M3

import androidx.compose.material3.Shapes

val AppShapes = Shapes(
    // M3 Shape parameters
)

Le seguenti mappature dei parametri Shape sono consigliate come punto di partenza:

M2 M3
N/A extraSmall
small small
medium medium
large large
N/A extraLarge

Componenti e layout

La maggior parte dei componenti e dei layout di M2 sono disponibili in M3. Ce ne sono, tuttavia, alcuni mancanti e nuovi che non esistevano in M2. Inoltre, alcuni componenti M3 hanno più varianti rispetto ai loro equivalenti in M2. In generale, le piattaforme API M3 cercano di essere il più simili possibile ai loro equivalenti più simili in M2.

Dati i sistemi aggiornati di colore, tipografia e forma, i componenti di M3 tendono a essere mappati in modo diverso ai nuovi valori dei temi. Ti consigliamo di controllare la directory dei token nel codice sorgente di Compose Material 3 come fonte attendibile per queste mappature.

Anche se alcuni componenti richiedono considerazioni speciali, le seguenti mappature delle funzioni sono consigliate come punto di partenza:

API mancanti:

M2 M3
androidx.compose.material.swipeable Non ancora disponibile

API sostituite:

M2 M3
androidx.compose.material.BackdropScaffold Non esiste un equivalente M3. Esegui la migrazione a Scaffold o BottomSheetScaffold.
androidx.compose.material.BottomDrawer Non esiste un equivalente M3. Esegui la migrazione a ModalBottomSheet

API rinominate:

M2 M3
androidx.compose.material.BottomNavigation androidx.compose.material3.NavigationBar
androidx.compose.material.BottomNavigationItem androidx.compose.material3.NavigationBarItem
androidx.compose.material.Chip androidx.compose.material3.AssistChip oppure androidx.compose.material3.SuggestionChip
androidx.compose.material.ModalBottomSheetLayout androidx.compose.material3.ModalBottomSheet
androidx.compose.material.ModalDrawer androidx.compose.material3.ModalNavigationDrawer

Tutte le altre API:

M2 M3
androidx.compose.material.AlertDialog androidx.compose.material3.AlertDialog
androidx.compose.material.Badge androidx.compose.material3.Badge
androidx.compose.material.BadgedBox androidx.compose.material3.BadgedBox
androidx.compose.material.BottomAppBar androidx.compose.material3.BottomAppBar
androidx.compose.material.BottomSheetScaffold androidx.compose.material3.BottomSheetScaffold
androidx.compose.material.Button androidx.compose.material3.Button
androidx.compose.material.Card androidx.compose.material3.Card
androidx.compose.material.Checkbox androidx.compose.material3.Checkbox
androidx.compose.material.CircularProgressIndicator androidx.compose.material3.CircularProgressIndicator
androidx.compose.material.Divider androidx.compose.material3.Divider
androidx.compose.material.DropdownMenu androidx.compose.material3.DropdownMenu
androidx.compose.material.DropdownMenuItem androidx.compose.material3.DropdownMenuItem
androidx.compose.material.ExposedDropdownMenuBox androidx.compose.material3.ExposedDropdownMenuBox
androidx.compose.material.ExtendedFloatingActionButton androidx.compose.material3.ExtendedFloatingActionButton
androidx.compose.material.FilterChip androidx.compose.material3.FilterChip
androidx.compose.material.FloatingActionButton androidx.compose.material3.FloatingActionButton
androidx.compose.material.Icon androidx.compose.material3.Icon
androidx.compose.material.IconButton androidx.compose.material3.IconButton
androidx.compose.material.IconToggleButton androidx.compose.material3.IconToggleButton
androidx.compose.material.LeadingIconTab androidx.compose.material3.LeadingIconTab
androidx.compose.material.LinearProgressIndicator androidx.compose.material3.LinearProgressIndicator
androidx.compose.material.ListItem androidx.compose.material3.ListItem
androidx.compose.material.NavigationRail androidx.compose.material3.NavigationRail
androidx.compose.material.NavigationRailItem androidx.compose.material3.NavigationRailItem
androidx.compose.material.OutlinedButton androidx.compose.material3.OutlinedButton
androidx.compose.material.OutlinedTextField androidx.compose.material3.OutlinedTextField
androidx.compose.material.RadioButton androidx.compose.material3.RadioButton
androidx.compose.material.RangeSlider androidx.compose.material3.RangeSlider
androidx.compose.material.Scaffold androidx.compose.material3.Scaffold
androidx.compose.material.ScrollableTabRow androidx.compose.material3.ScrollableTabRow
androidx.compose.material.Slider androidx.compose.material3.Slider
androidx.compose.material.Snackbar androidx.compose.material3.Snackbar
androidx.compose.material.Switch androidx.compose.material3.Switch
androidx.compose.material.Tab androidx.compose.material3.Tab
androidx.compose.material.TabRow androidx.compose.material3.TabRow
androidx.compose.material.Text androidx.compose.material3.Text
androidx.compose.material.TextButton androidx.compose.material3.TextButton
androidx.compose.material.TextField androidx.compose.material3.TextField
androidx.compose.material.TopAppBar androidx.compose.material3.TopAppBar
androidx.compose.material.TriStateCheckbox androidx.compose.material3.TriStateCheckbox

Scopri i componenti e i layout più recenti di M3 nella panoramica di riferimento dell'API Compose Material 3 e tieni d'occhio la pagina delle release per scoprire le API nuove e aggiornate.

impalcatura, snackbar e riquadro di navigazione a scomparsa

Confronto tra impalcature M2 e M3 con snackbar e cassetto di navigazione
Figura 5. impalcatura M2 con snackbar e cassetto di navigazione (a sinistra) rispetto a impalcatura M3 con snackbar e cassetto di navigazione (a destra).

Il ponteggio in M3 è diverso da M2. In M2 e M3, il layout componibile principale è denominato Scaffold, ma i pacchetti e i parametri di importazione sono diversi:

M2

import androidx.compose.material.Scaffold

Scaffold(
    // M2 scaffold parameters
)

M3

import androidx.compose.material3.Scaffold

Scaffold(
    // M3 scaffold parameters
)

La classe M2 Scaffold contiene un parametro backgroundColor ora denominato containerColor nella proprietà Scaffold M3:

M2

import androidx.compose.material.Scaffold

Scaffold(
    backgroundColor = …,
    content = { … }
)

M3

import androidx.compose.material3.Scaffold

Scaffold(
    containerColor = …,
    content = { … }
)

La classe M2 ScaffoldState non esiste più in M3 poiché contiene un parametro drawerState che non è più necessario. Per mostrare le snackbar con l'M3 Scaffold, utilizza invece SnackbarHostState:

M2

import androidx.compose.material.Scaffold
import androidx.compose.material.rememberScaffoldState

val scaffoldState = rememberScaffoldState()
val scope = rememberCoroutineScope()

Scaffold(
    scaffoldState = scaffoldState,
    content = {
        …
        scope.launch {
            scaffoldState.snackbarHostState.showSnackbar(…)
        }
    }
)

M3

import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState

val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()

Scaffold(
    snackbarHost = { SnackbarHost(snackbarHostState) },
    content = {
        …
        scope.launch {
            snackbarHostState.showSnackbar(…)
        }
    }
)

Tutti i parametri drawer* di Scaffold M2 sono stati rimossi da Scaffold M3. Questi includono parametri come drawerShape e drawerContent. Per mostrare un riquadro a scomparsa con l'M3 Scaffold, utilizza invece un riquadro di navigazione a scomparsa componibile, come ModalNavigationDrawer:

M2

import androidx.compose.material.DrawerValue
import
import androidx.compose.material.Scaffold
import androidx.compose.material.rememberDrawerState
import androidx.compose.material.rememberScaffoldState

val scaffoldState = rememberScaffoldState(
    drawerState = rememberDrawerState(DrawerValue.Closed)
)
val scope = rememberCoroutineScope()

Scaffold(
    scaffoldState = scaffoldState,
    drawerContent = { … },
    drawerGesturesEnabled = …,
    drawerShape = …,
    drawerElevation = …,
    drawerBackgroundColor = …,
    drawerContentColor = …,
    drawerScrimColor = …,
    content = {
        …
        scope.launch {
            scaffoldState.drawerState.open()
        }
    }
)

M3

import androidx.compose.material3.DrawerValue
import androidx.compose.material3.ModalDrawerSheet
import androidx.compose.material3.ModalNavigationDrawer
import androidx.compose.material3.Scaffold
import androidx.compose.material3.rememberDrawerState

val drawerState = rememberDrawerState(DrawerValue.Closed)
val scope = rememberCoroutineScope()

ModalNavigationDrawer(
    drawerState = drawerState,
    drawerContent = {
        ModalDrawerSheet(
            drawerShape = …,
            drawerTonalElevation = …,
            drawerContainerColor = …,
            drawerContentColor = …,
            content = { … }
        )
    },
    gesturesEnabled = …,
    scrimColor = …,
    content = {
        Scaffold(
            content = {
                …
                scope.launch {
                    drawerState.open()
                }
            }
        )
    }
)

Barra delle app superiore

Confronto tra impalcatura M2 e M3 con barra dell’app superiore e elenco scorrevole
Figura 6. scaffold M2 con barra delle app superiore ed elenco scorrevole (sinistra) rispetto a impalcatura M3 con barra delle app in alto ed elenco scorrevole (destra)

Le barre dell'app principali di M3 sono diverse da quelle di M2. In M2 e M3, il nome componibile della barra dell'app principale è TopAppBar, ma i pacchetti e i parametri di importazione sono diversi:

M2

import androidx.compose.material.TopAppBar

TopAppBar(…)

M3

import androidx.compose.material3.TopAppBar

TopAppBar(…)

Valuta la possibilità di utilizzare la M3 CenterAlignedTopAppBar se in precedenza stai centrando i contenuti all'interno dell'TopAppBar M2. È bene conoscere anche MediumTopAppBar e LargeTopAppBar.

Le barre dell'app principali M3 contengono un nuovo parametro scrollBehavior per offrire funzionalità diverse quando scorri la classe TopAppBarScrollBehavior, ad esempio la modifica dell'altitudine. Questa opzione funziona in combinazione con lo scorrimento dei contenuti tramite Modifer.nestedScroll. Ciò è stato possibile nell'elemento TopAppBar M2 modificando manualmente il parametro elevation:

M2

import androidx.compose.material.AppBarDefaults
import androidx.compose.material.Scaffold
import androidx.compose.material.TopAppBar

val state = rememberLazyListState()
val isAtTop by remember {
    derivedStateOf {
        state.firstVisibleItemIndex == 0 && state.firstVisibleItemScrollOffset == 0
    }
}

Scaffold(
    topBar = {
        TopAppBar(
            elevation = if (isAtTop) {
                0.dp
            } else {
                AppBarDefaults.TopAppBarElevation
            },
            …
        )
    },
    content = {
        LazyColumn(state = state) { … }
    }
)

M3

import androidx.compose.material3.Scaffold
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults

val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()

Scaffold(
    modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
    topBar = {
        TopAppBar(
            scrollBehavior = scrollBehavior,
            …
        )
    },
    content = {
        LazyColumn { … }
    }
)

Navigazione in basso / Barra di navigazione

Confronto tra la barra di navigazione inferiore M2 e la barra di navigazione M3
Figura 7. M2 in basso (sinistra) e barra di navigazione M3 (a destra).

La navigazione inferiore in M2 è stata rinominata barra di navigazione in M3. In M2 si trovano gli elementi componibili BottomNavigation e BottomNavigationItem, mentre in M3 si trovano gli elementi componibili NavigationBar e NavigationBarItem:

M2

import androidx.compose.material.BottomNavigation
import androidx.compose.material.BottomNavigationItem

BottomNavigation {
    BottomNavigationItem(…)
    BottomNavigationItem(…)
    BottomNavigationItem(…)
}

M3

import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem

NavigationBar {
    NavigationBarItem(…)
    NavigationBarItem(…)
    NavigationBarItem(…)
}

Pulsanti, pulsanti icona e FAB

Confronto tra i pulsanti M2 e M3
Figura 8. Pulsanti M2 (sinistra) e pulsanti M3 (destra)

I pulsanti, i pulsanti con le icone e i pulsanti di azione mobili (FAB) in M3 sono diversi da quelli di M2. M3 include tutti i componenti componibili a pulsante M2:

M2

import androidx.compose.material.Button
import androidx.compose.material.ExtendedFloatingActionButton
import androidx.compose.material.FloatingActionButton
import androidx.compose.material.IconButton
import androidx.compose.material.IconToggleButton
import androidx.compose.material.OutlinedButton
import androidx.compose.material.TextButton

// M2 buttons
Button(…)
OutlinedButton(…)
TextButton(…)
// M2 icon buttons
IconButton(…)
IconToggleButton(…)
// M2 FABs
FloatingActionButton(…)
ExtendedFloatingActionButton(…)

M3

import androidx.compose.material3.Button
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.IconButton
import androidx.compose.material3.IconToggleButton
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.TextButton

// M3 buttons
Button(…)
OutlinedButton(…)
TextButton(…)
// M3 icon buttons
IconButton(…)
IconToggleButton(…)
// M3 FABs
FloatingActionButton(…)
ExtendedFloatingActionButton(…)

M3 include anche nuove varianti di pulsanti. Scoprile nella panoramica di riferimento dell'API Compose Material 3.

Cambia

Confronto tra switch M2 e M3
Figura 9. interruttore M2 (sinistra) e interruttore M3 (destra).

La modalità Cambia in M3 è diversa rispetto a M2. In M2 e M3, lo switch componibile è denominato Switch, ma i pacchetti di importazione sono diversi:

M2

import androidx.compose.material.Switch

Switch(…)

M3

import androidx.compose.material3.Switch

Switch(…)

Superficie e altitudine

Confronto tra l'elevazione della superficie M2 e l'elevazione della superficie M3 nei temi chiari e scuri
Figura 10. Elevazione della superficie M2 rispetto all'elevazione della superficie M3 in tema chiaro (sinistra) e tema scuro (destra).

I sistemi di superficie e di elevazione di M3 sono diversi da quelli di M2. Esistono due tipi di elevazione in M3:

  • Altitudine delle ombre (promette un'ombra, come M2)
  • Elevazione tonale (viene sovrapposto un colore, nuovo in M3)

In Compose, questo si applica alla funzione M2 Surface e alla funzione M3 Surface:

M2

import androidx.compose.material.Surface

Surface(
    elevation = …
) { … }

M3

import androidx.compose.material3.Surface

Surface(
    shadowElevation = …,
    tonalElevation = …
) { … }

Puoi utilizzare i valori elevation Dp in M2 per shadowElevation e/o tonalElevation in M3, a seconda della preferenza di progettazione dell'interfaccia utente e dell'interfaccia utente. Surface è l'elemento componibile di supporto alla base della maggior parte dei componenti, pertanto i componenti componibili potrebbero esporre anche i parametri di elevazione di cui devi eseguire la migrazione nello stesso modo.

L'elevazione tonale in M3 sostituisce il concetto di overlay di elevazione nei temi scuri M2 . Di conseguenza, ElevationOverlay e LocalElevationOverlay non esistono in M3 e LocalAbsoluteElevation in M2 è cambiato in LocalAbsoluteTonalElevation in M3.

Enfasi e contenuti alpha

Confronto tra le icone M2 e M3 e l'enfasi del testo
Figura 11. Icona M2 ed enfasi del testo (a sinistra) rispetto a icona M3 ed enfasi del testo (a destra)

L'enfasi in M3 è notevolmente diversa da quella in M2. In M2 l'enfasi prevedeva l'uso di colori "on" con determinati valori alfa per differenziare i contenuti come testo e icone. Nella versione M3 sono ora disponibili due approcci diversi:

  • Utilizzo dei colori "on" insieme a quelli "variant on" (in base alla variante) del sistema di colori M3 espanso.
  • Utilizzare spessori diversi per il testo.

Di conseguenza, ContentAlpha e LocalContentAlpha non esistono in M3 e devono essere sostituiti.

Le mappature riportate di seguito sono consigliate come punto di partenza:

M2 M3
onSurface con ContentAlpha.high onSurface in generale, FontWeight.Medium - FontWeight.Black per il testo
onSurface con ContentAlpha.medium onSurfaceVariant in generale, FontWeight.Thin - FontWeight.Normal per il testo
onSurface con ContentAlpha.disabled onSurface.copy(alpha = 0.38f)

Ecco un esempio di enfasi delle icone in M2 e M3:

M2

import androidx.compose.material.ContentAlpha
import androidx.compose.material.LocalContentAlpha

// High emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.high) {
    Icon(…)
}
// Medium emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
    Icon(…)
}
// Disabled emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.disabled) {
    Icon(…)
}

M3

import androidx.compose.material3.LocalContentColor

// High emphasis
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurface) {
    Icon(…)
}
// Medium emphasis
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurfaceVariant) {
    Icon(…)
}
// Disabled emphasis
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f)) {
    Icon(…)
}

Ecco un esempio di enfasi del testo in M2 e M3:

M2

import androidx.compose.material.ContentAlpha
import androidx.compose.material.LocalContentAlpha

// High emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.high) {
    Text(…)
}
// Medium emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
    Text(…)
}
// Disabled emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.disabled) {
    Text(…)
}

M3

import androidx.compose.material3.LocalContentColor

// High emphasis
Text(
    …,
    fontWeight = FontWeight.Bold
)
// Medium emphasis
Text(
    …,
    fontWeight = FontWeight.Normal
)
// Disabled emphasis
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f)) {
    Text(
        …,
        fontWeight = FontWeight.Normal
    )
}

Sfondi e contenitori

Gli sfondi in M2 sono chiamati "container" in M3. In generale, puoi sostituire i parametri background* in M2 con container* in M3, utilizzando gli stessi valori. Ecco alcuni esempi:

M2

Badge(
    backgroundColor = MaterialTheme.colors.primary
) { … }

M3

Badge(
    containerColor = MaterialTheme.colorScheme.primary
) { … }

Visualizza l'interoperabilità

Se la tua app include l'interoperabilità di tipo Viste o XML e utilizza la libreria Adattatore tema di composizione M3-Android, devi utilizzare la versione M3:

M2

implementation "com.google.android.material:compose-theme-adapter:$compose-theme-adapter-version"

M3

implementation "com.google.android.material:compose-theme-adapter-3:$compose-theme-adapter-3-version"

Consulta le versioni più recenti nella pagina delle release dell'adattatore del tema di MDC-Android Compose.

La principale differenza tra le versioni M2 e M3 è i rispettivi componenti componibili MdcTheme e Mdc3Theme:

M2

import com.google.android.material.composethemeadapter.MdcTheme

MdcTheme {
    // M2 content
}

M3

import com.google.android.material.composethemeadapter3.Mdc3Theme

Mdc3Theme {
    // M3 content
}

Per ulteriori informazioni, leggi il file README.

Per ulteriori informazioni sulla migrazione da Material 2 a Material 3 in Viste, consulta la guida alla migrazione a Material Design 3.

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

Documenti

App di esempio

Video

Riferimento API e codice sorgente