Material Design 3 è la nuova evoluzione di Material Design. Include temi, componenti e funzionalità di personalizzazione Material You aggiornati, 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 si concentra sulla migrazione dalla libreria Jetpack Compose Material (androidx.compose.material) alla libreria Jetpack Compose Material 3 (androidx.compose.material3).
Approcci
In generale, non dovresti utilizzare sia M2 che M3 in una singola app a lungo termine. Ciò è dovuto al fatto che i due sistemi di progettazione e le rispettive librerie differiscono significativamente in termini di design UX/UI e implementazioni di Compose.
La tua app potrebbe usare un sistema di progettazione, ad esempio uno creato con Figma. In questi casi, ti consigliamo vivamente anche di eseguire la migrazione da M2 a M3 da parte tua o del tuo team di progettazione prima di iniziare la migrazione di Compose. Non ha senso eseguire la migrazione di un'app a M3 se il design UX/UI è basato su M2.
Inoltre, l'approccio alla migrazione deve variare in base alle dimensioni, alla complessità e al design UX/UI dell'app. In questo modo, puoi ridurre al minimo l'impatto sulla base di codice. Ti consigliamo di adottare un approccio graduale alla migrazione.
Quando eseguire la migrazione
Ti consigliamo di avviare la migrazione il prima possibile. Tuttavia, è importante valutare se la tua app è in una posizione realistica per eseguire la migrazione completa da M2 a M3. Prima di iniziare, valuta la possibilità di esaminare alcuni scenari di blocco:
Scenario | Approccio consigliato |
---|---|
Nessun blocco | Avvia la migrazione graduale |
Un componente di M2 non è ancora disponibile in M3. Consulta la sezione Componenti e layout di seguito. | Avvia la migrazione graduale |
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 design da M2 a M3, quindi inizia la migrazione graduale |
Anche se sei interessato dagli scenari precedenti, devi adottare un approccio graduale alla migrazione prima di eseguire il commit e rilasciare un aggiornamento dell'app. In questi casi, utilizzerai M2 e M3 affiancati e eliminerai gradualmente M2 durante la migrazione a M3.
Approccio graduale
I passaggi generali per una migrazione a fasi sono i seguenti:
- Aggiungi la dipendenza M3 insieme alla dipendenza M2.
- Aggiungi le versioni M3 dei temi dell'app insieme alle versioni M2 dei temi dell'app.
- Esegui la migrazione di singoli moduli, schermate o componenti composibili a M3, a seconda delle dimensioni e della complessità dell'app (per maggiori dettagli, consulta le sezioni seguenti).
- Una volta completata la migrazione, rimuovi le versioni M2 dei temi dell'app.
- Rimuovi la dipendenza da 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"
Vedi le ultime versioni di M3 nella pagina delle release di Compose Material 3.
Le altre dipendenze di Material al di fuori delle librerie principali M2 e M3 non sono cambiate. Utilizzano una combinazione di pacchetti e versioni M2 e M3, ma questo non influisce sulla migrazione. Possono essere utilizzati così come sono con M3:
Raccolta | Pacchetto e versione |
---|---|
Creare icone Material | androidx.compose.material:material-icons-*:$m2-version |
Effetto Material Ripple | androidx.compose.material:material-ripple:$m2-version |
API sperimentali
Alcune API M3 sono considerate sperimentali. In questi casi, devi attivare la funzionalità a livello di funzione o 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 composable del tema è 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
Il sistema di colori della versione M3 è molto diverso da quello della versione M2. Il
numero di parametri di colore è aumentato, hanno nomi diversi e si mappano diversamente ai componenti M3. In Compose, 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
}
Date le differenze significative tra i sistemi di colori M2 e M3, non esiste una mappatura ragionevole per i parametri Color
. Utilizza invece lo strumento Material
Theme Builder 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. Come punto di partenza, ti consigliamo le seguenti mappature:
M2 | Generatore di temi Material |
---|---|
primary |
Principale |
primaryVariant |
Secondario |
secondary |
Terziario |
surface o background |
Neutra |
Puoi copiare i valori dei codici esadecimali dei colori per i temi chiari e scuri dallo strumento e utilizzarli per implementare un'istanza ColorScheme M3. In alternativa, Material Theme Builder può esportare il codice Compose.
isLight
A differenza della classe M2 Colors
, la classe M3 ColorScheme
non include un parametro
isLight
. In generale, dovresti provare a modellare tutto ciò che richiede queste informazioni a livello di tema. Ad esempio:
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 la guida sui sistemi di progettazione personalizzati in Compose.
Colore dinamico
Una nuova funzionalità di M3 è il colore dinamico. Anziché utilizzare colori personalizzati, un M3 ColorScheme
può utilizzare i colori dello sfondo del dispositivo su Android 12 e versioni successive, utilizzando le seguenti funzioni:
Tipografia
Il sistema di tipografia in M3 è diverso da quello di M2. Il numero
dei parametri tipografici è più o meno uguale, ma hanno nomi diversi e
mappano in modo diverso ai componenti M3. In Compose, 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
)
Come punto di partenza, ti consigliamo le seguenti mappature dei parametri TextStyle
:
M2 | M3 |
---|---|
h1 |
displayLarge |
h2 |
displayMedium |
h3 |
displaySmall |
N/D | headlineLarge |
h4 |
headlineMedium |
h5 |
headlineSmall |
h6 |
titleLarge |
subtitle1 |
titleMedium |
subtitle2 |
titleSmall |
body1 |
bodyLarge |
body2 |
bodyMedium |
caption |
bodySmall |
button |
labelLarge |
N/D | labelMedium |
overline |
labelSmall |
Forma
Il sistema di forme in M3 è diverso da quello in M2. Il numero di parametri della forma è aumentato, hanno nomi diversi e vengono mappati in modo diverso ai componenti M3. In Compose, 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
)
Come punto di partenza, ti consigliamo le seguenti mappature dei parametri Shape
:
M2 | M3 |
---|---|
N/D | extraSmall |
small |
small |
medium |
medium |
large |
large |
N/D | extraLarge |
Componenti e layout
La maggior parte dei componenti e dei layout di M2 è disponibile in M3. Tuttavia, ne mancano alcune e ne sono state aggiunte di nuove che non esistevano in M2. Inoltre, alcuni componenti M3 presentano più variazioni rispetto ai componenti M2 equivalenti. In generale, le API M3 cercano di essere il più simili possibile ai loro equivalenti più vicini in M2.
Dati i sistemi di colori, tipografia e forme aggiornati, i componenti M3 tendono a mapparsi diversamente ai nuovi valori di temi. Ti consigliamo di consultare la directory dei token nel codice sorgente di Compose Material 3 come fonte di verità per queste mappature.
Sebbene alcuni componenti richiedano considerazioni speciali, come punto di partenza sono consigliati i seguenti mappaggi delle funzioni:
API mancanti:
M2 | M3 |
---|---|
androidx.compose.material.swipeable |
Non ancora disponibile |
API sostituite:
M2 | M3 |
---|---|
androidx.compose.material.BackdropScaffold |
Nessun equivalente M3, esegui la migrazione a Scaffold o BottomSheetScaffold |
androidx.compose.material.BottomDrawer |
Nessun equivalente M3, esegui la migrazione a ModalBottomSheet |
API rinominate:
Tutte le altre API:
Esamina i componenti e i layout M3 più recenti nella panoramica dei riferimenti dell'API Compose Material 3 e tieni d'occhio la pagina delle release per le API nuove e aggiornate.
Framwork, snackbar e riquadro di navigazione a scomparsa
La struttura in M3 è diversa da quella in M2. Sia in M2 che in M3, il composable del layout 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
)
L'elemento M2 Scaffold
contiene un parametro backgroundColor
ora denominato containerColor
nell'elemento M3 Scaffold
:
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 perché contiene un parametro
drawerState
non più necessario. Per mostrare barre di appostamento con
Scaffold
M3, utilizza 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. Sono inclusi parametri come drawerShape
e
drawerContent
. Per mostrare un riquadro con l'elemento M3 Scaffold
, utilizza un composable del riquadro di navigazione, ad esempio 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 in alto
Le barre delle app principali nella versione M3 sono diverse da quelle nella versione M2. Sia in M2 che in M3, il composable della barra delle app superiore principale è denominato TopAppBar
, ma i pacchetti di importazione e i parametri sono diversi:
M2
import androidx.compose.material.TopAppBar
TopAppBar(…)
M3
import androidx.compose.material3.TopAppBar
TopAppBar(…)
Prendi in considerazione l'utilizzo del formato M3 CenterAlignedTopAppBar
se in precedenza centravi i contenuti all'interno del formato M2 TopAppBar
. È bene conoscere anche MediumTopAppBar
e LargeTopAppBar
.
Le barre delle app superiori M3 contengono un nuovo parametro scrollBehavior
per fornire funzionalità diverse durante lo scorrimento della classe TopAppBarScrollBehavior
, ad esempio la modifica dell'elevazione. Questa opzione funziona in combinazione con lo scorrimento dei contenuti tramite
Modifer.nestedScroll
. In M2 TopAppBar
era possibile
modificare 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
La navigazione in basso in M2 è stata rinominata in barra di navigazione in M3. In M2 ci sono i componibili BottomNavigation
e BottomNavigationItem
, mentre nell'M3 ci sono i 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 con icone e pulsanti flottanti di grandi dimensioni
I pulsanti, i pulsanti con icone e i pulsanti di azione popup (FAB) in M3 sono diversi da quelli in M2. M3 include tutti i composabili del 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. Consulta la panoramica dei riferimenti dell'API Compose Material 3.
Cambia
Switch in M3 è diverso da M2. Sia in M2 che in M3, il composable di switch è denominato Switch
, ma i pacchetti di importazione sono diversi:
M2
import androidx.compose.material.Switch
Switch(…)
M3
import androidx.compose.material3.Switch
Switch(…)
Superfici e altitudine
I sistemi di rilievi e di elevazione in M3 sono diversi da quelli in M2. Esistono due tipi di elevazione in M3:
- Elevazione ombra (proietta un'ombra, come M2)
- Elevazione tonale (sovrapposizione a un colore, nuovo di M3)
In Componi, 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 sia per shadowElevation
e/o tonalElevation
in M3, a seconda della preferenza di progettazione UX/UI.
Surface
è il composable di supporto alla maggior parte dei componenti, pertanto i composable dei componenti potrebbero esporre anche 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 di M2 . Di conseguenza, ElevationOverlay
e LocalElevationOverlay
non esistono nella versione M3, mentre LocalAbsoluteElevation
nella versione M2 è diventata
LocalAbsoluteTonalElevation
nella versione M3.
Enfasi e contenuti alpha
L'enfasi in M3 è notevolmente diversa da quella in M2. In M2, l'enfasi prevedeva l'utilizzo di colori on con determinati valori alpha per differenziare i contenuti come testo e icone. Nella versione M3 esistono ora due approcci diversi:
- Utilizzo dei colori on insieme alla variante on del sistema di colori M3 ampliato.
- Utilizzare spessori di carattere diversi per il testo.
Di conseguenza, ContentAlpha
e LocalContentAlpha
non esistono in M3 e devono essere sostituiti.
Come punto di partenza, ti consigliamo le seguenti mappature:
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 rispetto a 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(…)
}
Di seguito sono riportati alcuni esempi di enfasi del testo nelle versioni 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 container
Gli sfondi in M2 sono contenitori denominati in M3. In generale, puoi sostituire i parametri background*
in M2 con container*
in M3, utilizzando gli stessi valori.
Ad esempio:
M2
Badge(
backgroundColor = MaterialTheme.colors.primary
) { … }
M3
Badge(
containerColor = MaterialTheme.colorScheme.primary
) { … }
Link utili
Per saperne di più sulla migrazione da M2 a M3 in Compose, consulta le seguenti risorse aggiuntive.
Documenti
App di esempio
- App di esempio Reply M3
- Migrazione da M2 a M3 dell'app Jetchat di esempio
- Migrazione dell'app di esempio Jetnews da M2 a M3
- Ora nell'app hero Android M3 :modulo core-designsystem
Video
Riferimento API e codice sorgente
Consigliati per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- Material Design 2 in Scrivi
- Material Design 3 in Scrittura
- Sistemi di progettazione personalizzati in Compose