In Compose von Material 2 zu Material 3 migrieren

Material Design 3 ist die nächste Entwicklung von Material Design. Dazu gehören aktualisierte Designs, Komponenten und Material You-Personalisierungsfunktionen wie dynamische Farben. Es ist eine Aktualisierung von Material Design 2 und passt zum neuen visuellen Stil und der neuen System-UI unter Android 12 und höher.

In diesem Leitfaden geht es um die Migration von der Jetpack-Bibliothek „Compose Material“ (androidx.compose.material) zur Jetpack-Bibliothek „Compose Material 3 (androidx.compose.material3)“.

Ansätze

Im Allgemeinen sollten Sie M2 und M3 nicht langfristig in einer App verwenden. Das liegt daran, dass sich die beiden Designsysteme und die jeweiligen Bibliotheken in Bezug auf ihre UX/UI-Designs und Compose-Implementierungen erheblich unterscheiden.

Ihre App kann ein Designsystem verwenden, z. B. eines, das mit Figma erstellt wurde. In solchen Fällen empfehlen wir außerdem dringend, dass Sie oder Ihr Designteam die Migration von M2 zu M3 vor der Migration von Compose starten. Es macht keinen Sinn, eine Anwendung zu M3 zu migrieren, wenn ihr UX-/UI-Design auf M2 basiert.

Darüber hinaus sollte sich Ihr Migrationsansatz je nach Größe, Komplexität und UX-/UI-Design Ihrer Anwendung unterscheiden. Auf diese Weise können Sie die Auswirkungen auf Ihre Codebasis minimieren. Sie sollten die Migration schrittweise durchführen.

Migrationszeitpunkt

Sie sollten die Migration so bald wie möglich starten. Sie müssen jedoch überlegen, ob Ihre Anwendung in einer realistischen Position ist, vollständig von M2 zu M3 zu migrieren. Es gibt einige Blocker-Szenarien, die Sie untersuchen sollten, bevor Sie beginnen:

Szenario Empfohlener Ansatz
Keine „Hindernisse“ Phasenweise Migration starten
Eine Komponente aus M2 ist in M3 noch nicht verfügbar. Weitere Informationen finden Sie unten im Abschnitt Komponenten und Layouts. Phasenweise Migration starten
Sie oder Ihr Designteam haben das Designsystem der App nicht von M2 zu M3 migriert. Designsystem von M2 zu M3 migrieren und dann mit der schrittweisen Migration beginnen

Auch wenn Sie von den oben genannten Szenarien betroffen sind, sollten Sie die Migration schrittweise vornehmen, bevor Sie ein Anwendungsupdate festlegen und veröffentlichen. In diesen Fällen würden Sie M2 und M3 parallel verwenden und M2 während der Migration zu M3 schrittweise auslaufen lassen.

Gestaffelter Ansatz

Im Allgemeinen sind folgende Schritte für eine stufenweise Migration erforderlich:

  1. Fügen Sie die M3- und die M2-Abhängigkeit hinzu.
  2. Fügen Sie M3-Versionen Ihrer App-Designs sowie M2-Versionen Ihrer App-Designs hinzu.
  3. Migrieren Sie einzelne Module, Bildschirme oder zusammensetzbare Funktionen je nach Größe und Komplexität Ihrer Anwendung zu M3. Weitere Informationen finden Sie in den folgenden Abschnitten.
  4. Entfernen Sie nach der vollständigen Migration die M2-Versionen Ihrer App-Designs.
  5. M2-Abhängigkeit entfernen.

Abhängigkeiten

Für M3 gibt es ein separates Paket und eine separate Version für M2:

M2

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

M3

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

Die neuesten M3-Versionen finden Sie auf der Seite mit den Releases von Composer Material 3.

Andere Material-Abhängigkeiten außerhalb der M2- und M3-Hauptbibliotheken haben sich nicht geändert. Sie verwenden eine Mischung aus M2- und M3-Paketen und -Versionen, hat aber keinen Einfluss auf die Migration. Sie können unverändert mit M3 verwendet werden:

Mediathek Paket und Version
Symbole für Material Design androidx.compose.material:material-icons-*:$m2-version
„Material Wellen“ komponieren androidx.compose.material:material-ripple:$m2-version
Compose Material 3-Fenstergrößenklasse androidx.compose.material3:material3-window-size-class:$m3-version

Experimentelle APIs

Einige M3 APIs gelten als experimentell. In solchen Fällen müssen Sie die Aktivierung auf Funktions- oder Dateiebene mithilfe der Annotation ExperimentalMaterial3Api vornehmen:

import androidx.compose.material3.ExperimentalMaterial3Api

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

Designs

Sowohl in M2 als auch in M3 heißt das Thema der zusammensetzbaren Funktion MaterialTheme, die Importpakete und Parameter unterscheiden sich jedoch:

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
}

Farbe

Vergleich der Farbsysteme M2 und M3
Abbildung 1: M2-Farbsystem (links) vs. M3-Farbsystem (rechts)

Das Farbsystem in M3 unterscheidet sich erheblich von M2. Die Anzahl der Farbparameter ist gestiegen, sie haben unterschiedliche Namen und werden den M3-Komponenten anders zugeordnet. In „Compose“ gilt dies für die M2-Klasse Colors, die M3-Klasse ColorScheme und zugehörige Funktionen:

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
}

Angesichts der erheblichen Unterschiede zwischen den Farbsystemen M2 und M3 gibt es keine sinnvolle Zuordnungen für die Color-Parameter. Verwenden Sie stattdessen den Material Theme Builder, um ein M3-Farbschema zu generieren. Verwenden Sie die M2-Farben im Tool als "zentrale" Quellfarben, die vom Tool in die vom M3-Farbschema verwendeten Farbpaletten erweitert werden. Die folgenden Zuordnungen werden als Ausgangspunkt empfohlen:

M2 Tool zum Erstellen von Material Design
primary Primäre Zielgruppe
primaryVariant Sekundär
secondary Dritter Track
surface oder background Neutral
M2-Farben, die im Material Theme Builder verwendet werden, um ein M3-Farbschema zu generieren
Abbildung 2: Die M2-Farben von Jetchat, die im Material Theme Builder verwendet werden, um ein M3-Farbschema zu generieren.

Sie können die Hexadezimalcodes der Farbe für helle und dunkle Designs aus dem Tool kopieren und zum Implementieren einer M3 ColorScheme-Instanz verwenden. Alternativ kann der Material Theme Builder den Compose-Code exportieren.

isLight

Im Gegensatz zur M2-Klasse Colors enthält die M3-Klasse ColorScheme keinen isLight-Parameter. Generell sollten Sie versuchen, das, was diese Informationen benötigt, auf Themenebene zu modellieren. Beispiele:

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
        …
    }
}

Weitere Informationen finden Sie im Leitfaden Benutzerdefinierte Designsysteme im Erstellungsleitfaden.

Dynamische Farben

Eine neue Funktion in M3 ist die dynamische Farbe. Anstelle von benutzerdefinierten Farben kann ein M3-ColorScheme unter Android 12 und höher Gerätehintergrundfarben mit den folgenden Funktionen verwenden:

Typografie

Vergleich der Typografiesysteme M2 und M3
Abbildung 3: Typografiesystem M3 (links) im Vergleich zum M2-Typografiesystem (rechts)

Das Typografiesystem in M3 unterscheidet sich von M2. Die Anzahl der Typografieparameter ist ungefähr gleich, sie haben jedoch unterschiedliche Namen und werden den M3-Komponenten unterschiedlich zugeordnet. In „Compose“ gilt dies für die M2-Klasse Typography und die M3-Klasse 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
)

Als Ausgangspunkt werden die folgenden TextStyle-Parameterzuordnungen empfohlen:

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

Form

Vergleich der Formsysteme M2 und M3
Abbildung 4: M2-Formsystem (links) vs. M3-Formsystem (rechts)

Das Formsystem in M3 unterscheidet sich von M2. Die Anzahl der Formparameter hat zugenommen, sie sind unterschiedlich benannt und werden den M3-Komponenten anders zugeordnet. In Compose gilt dies für die M2-Klasse Shapes und die M3-Klasse 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
)

Als Ausgangspunkt werden die folgenden Shape-Parameterzuordnungen empfohlen:

M2 M3
extraSmall
small small
medium medium
large large
extraLarge

Komponenten und Layouts

Die meisten Komponenten und Layouts von M2 sind in M3 verfügbar. Es gibt jedoch einige fehlende oder neue, die es in M2 noch nicht gab. Darüber hinaus haben einige M3-Komponenten mehr Variationen als ihre Äquivalente in M2. Im Allgemeinen versuchen die M3 API-Oberflächen, den Äquivalenten in M2 so ähnlich wie möglich zu sein.

Aufgrund der aktualisierten Farb-, Typografie- und Formsysteme werden die M3-Komponenten den neuen Themenwerten tendenziell anders zugeordnet. Es empfiehlt sich, als Referenz für diese Zuordnungen das Tokenverzeichnis im Quellcode von Compose Material 3 zu prüfen.

Während für einige Komponenten besondere Überlegungen erforderlich sind, werden die folgenden Funktionszuordnungen als Ausgangspunkt empfohlen:

Fehlende APIs:

M2 M3
androidx.compose.material.swipeable Noch nicht verfügbar

Ersetzte APIs:

M2 M3
androidx.compose.material.BackdropScaffold Kein M3-Äquivalent, stattdessen zu Scaffold oder BottomSheetScaffold migrieren
androidx.compose.material.BottomDrawer Kein M3-Äquivalent, stattdessen zu ModalBottomSheet migrieren

Umbenannte APIs:

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 oder androidx.compose.material3.SuggestionChip
androidx.compose.material.ModalBottomSheetLayout androidx.compose.material3.ModalBottomSheet
androidx.compose.material.ModalDrawer androidx.compose.material3.ModalNavigationDrawer

Alle anderen APIs:

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

Die neuesten M3-Komponenten und -Layouts finden Sie in der Referenzübersicht zur Composer Material 3 API. Auf der Releaseseite finden Sie neue und aktualisierte APIs.

Gerüst, Snackbars und Navigationsleiste

Vergleich von M2- und M3-Gerüst mit Snackbar und Navigationsleiste
Abbildung 5: M2-Gerüst mit Snackbar und Navigationsleiste (links) im Vergleich zu M3-Gerüst mit Snackbar und Navigationsleiste (rechts).

Scaffold in M3 unterscheidet sich von M2. Sowohl in M2 als auch in M3 heißt das Hauptlayout der zusammensetzbaren Funktion Scaffold, die Importpakete und Parameter unterscheiden sich jedoch:

M2

import androidx.compose.material.Scaffold

Scaffold(
    // M2 scaffold parameters
)

M3

import androidx.compose.material3.Scaffold

Scaffold(
    // M3 scaffold parameters
)

Der M2-Scaffold enthält einen backgroundColor-Parameter, der in M3 Scaffold jetzt mit containerColor bezeichnet wird:

M2

import androidx.compose.material.Scaffold

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

M3

import androidx.compose.material3.Scaffold

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

Die M2-Klasse ScaffoldState ist in M3 nicht mehr vorhanden, da sie den Parameter drawerState enthält, der nicht mehr benötigt wird. Zum Anzeigen von Snackbars mit dem M3-Scaffold verwenden Sie stattdessen 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(…)
        }
    }
)

Alle drawer*-Parameter aus dem M2-Scaffold wurden aus dem M3-Scaffold entfernt. Dazu gehören Parameter wie drawerShape und drawerContent. Wenn Sie eine Leiste mit dem M3-Scaffold einblenden möchten, verwenden Sie stattdessen eine zusammensetzbare Navigationsleiste wie 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()
                }
            }
        )
    }
)

Obere App-Leiste

Vergleich des M2- und M3-Gerüsts mit der oberen App-Leiste und der gescrollten Liste
Abbildung 6: M2-Gerüst mit oberer App-Leiste und scrollbarer Liste (links) im Vergleich zu M3-Gerüst mit oberer App-Leiste und gescrollter Liste (rechts)

Die Top-App-Leisten in M3 unterscheiden sich von denen in M2. Sowohl in M2 als auch in M3 heißt die zusammensetzbare Hauptfunktion der oberen App-Leiste TopAppBar, die Importpakete und Parameter unterscheiden sich jedoch:

M2

import androidx.compose.material.TopAppBar

TopAppBar(…)

M3

import androidx.compose.material3.TopAppBar

TopAppBar(…)

Verwenden Sie gegebenenfalls M3 CenterAlignedTopAppBar, wenn Sie zuvor Inhalte in M2 TopAppBar zentriert haben. Es ist außerdem gut, auch die MediumTopAppBar und LargeTopAppBar zu kennen.

Die oberen M3-App-Leisten enthalten einen neuen scrollBehavior-Parameter, der beim Scrollen durch die Klasse TopAppBarScrollBehavior unterschiedliche Funktionen bietet, z. B. das Ändern der Höhe. Dies funktioniert in Verbindung mit scrollbarem Inhalt über Modifer.nestedScroll. Dies war im M2-TopAppBar durch manuelles Ändern des elevation-Parameters möglich:

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 { … }
    }
)

Navigationsleiste unten / Navigationsleiste

Vergleich der M2-Navigation unten und der M3-Navigationsleiste
Abbildung 7: N2-Navigation unten (links) im Vergleich zur M3-Navigationsleiste (rechts).

Die Navigation am unteren Rand wurde in M2 in M3 in Navigationsleiste umbenannt. In M2 gibt es die zusammensetzbaren Funktionen BottomNavigation und BottomNavigationItem, in M3 die zusammensetzbaren Funktionen NavigationBar und 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(…)
}

Schaltflächen, Symbolschaltflächen und FABs

Vergleich der Schaltflächen M2 und M3
Abbildung 8: M2-Tasten (links) im Vergleich zu M3-Tasten (rechts)

Schaltflächen, Symbolschaltflächen und unverankerte Aktionsschaltflächen (FABs) in M3 unterscheiden sich von denen in M2. M3 enthält alle zusammensetzbaren Funktionen der M2-Schaltfläche:

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 umfasst auch neue Schaltflächenvarianten. Weitere Informationen finden Sie in der Übersicht über die Compose Material 3 API-Referenz.

Wechseln

M2- und M3-Switches im Vergleich
Abbildung 9: M2-Schalter (links) vs. M3-Schalter (rechts).

Der Wechsel in M3 unterscheidet sich von M2. Sowohl in M2 als auch in M3 heißt die zusammensetzbare Funktion Switch, die Importpakete unterscheiden sich jedoch:

M2

import androidx.compose.material.Switch

Switch(…)

M3

import androidx.compose.material3.Switch

Switch(…)

Oberflächen und Höhen

Vergleich der Oberflächenhöhen von M2 und M3 bei hellen und dunklen Designs
Abbildung 10: M2-Oberflächenverstärkung im Vergleich zu M3-Oberflächen im hellen Design (links) und dunklem Design (rechts)

Die Oberflächen- und Höhensysteme in M3 unterscheiden sich von M2. In M3 gibt es zwei Arten von Höhendaten:

  • Schattenhöhe (wirft einen Schatten, wie bei M2)
  • Farbton (überdeckt eine Farbe, neu in M3)

In „Compose“ gilt dies für die M2-Funktion Surface und die M3-Funktion Surface:

M2

import androidx.compose.material.Surface

Surface(
    elevation = …
) { … }

M3

import androidx.compose.material3.Surface

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

Sie können die elevation-Werte Dp in M2 je nach Präferenz für das UX-/UI-Design sowohl für shadowElevation als auch für tonalElevation in M3 verwenden. Surface ist die sichernde zusammensetzbare Funktion hinter den meisten Komponenten. Daher können zusammensetzbare Komponenten auch Höhenparameter zur Verfügung stellen, die Sie auf die gleiche Weise migrieren müssen.

Die Farbtonhöhe in M3 ersetzt das Konzept der Höhen-Overlays in den dunklen M2-Designs . Daher sind ElevationOverlay und LocalElevationOverlay in M3 nicht vorhanden und LocalAbsoluteElevation in M2 wurde in M3 zu LocalAbsoluteTonalElevation geändert.

Betonung und Inhalt (Alpha)

Vergleich der Symbol- und Textbetonung M2 und M3
Abbildung 11: M2-Symbol und Textbetonung (links) im Vergleich zu M3-Symbol und Textbetonung (rechts)

Die Betonung in M3 unterscheidet sich erheblich von M2. Bei der M2-Betonung wurde die Verwendung von „An“-Farben mit bestimmten Alphawerten zur Unterscheidung von Inhalten wie Text und Symbolen einbezogen. In M3 gibt es jetzt einige unterschiedliche Ansätze:

  • Verwendung von „An“-Farben zusammen mit den „Varianten“-Farben aus dem erweiterten M3-Farbsystem.
  • Unterschiedliche Schriftstärken für Text verwenden

Daher sind ContentAlpha und LocalContentAlpha nicht in M3 vorhanden und müssen ersetzt werden.

Die folgenden Zuordnungen werden als Ausgangspunkt empfohlen:

M2 M3
onSurface mit ContentAlpha.high onSurface im Allgemeinen, FontWeight.MediumFontWeight.Black für Text
onSurface mit ContentAlpha.medium onSurfaceVariant im Allgemeinen, FontWeight.ThinFontWeight.Normal für Text
onSurface mit ContentAlpha.disabled onSurface.copy(alpha = 0.38f)

Hier ist ein Beispiel für die Symbolbetonung in M2 im Vergleich zu 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(…)
}

Hier ist ein Beispiel für die Textbetonung in M2 im Vergleich zu 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
    )
}

Hintergründe und Container

Hintergründe in M2 werden in M3 als „Container“ bezeichnet. Im Allgemeinen können Sie background*-Parameter in M2 durch container* in M3 mit denselben Werten ersetzen. Beispiele:

M2

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

M3

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

Interoperabilität von Ansichten

Wenn Ihre App Ansichten- oder XML-Interoperabilität bietet und die MDC-Android-Bibliothek „Compose Theme Adapter“ nutzt, müssen Sie die Version M3 verwenden:

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"

Die aktuellen Versionen finden Sie auf der Seite mit den Releases des MC-Android Compose Theme Adapters.

Der Hauptunterschied zwischen den Versionen M2 und M3 besteht in den jeweiligen zusammensetzbaren Funktionen MdcTheme und Mdc3Theme:

M2

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

MdcTheme {
    // M2 content
}

M3

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

Mdc3Theme {
    // M3 content
}

Weitere Informationen finden Sie in der Readme-Datei.

Weitere Informationen zur Migration von Material 2 zu Material 3 in Ansichten finden Sie in der Anleitung zur Migration zu Material Design 3.

Weitere Informationen zur Migration von M2 zu M3 in Compose finden Sie in den folgenden zusätzlichen Ressourcen.

Docs

Beispiel-Apps

Videos

API-Referenz und Quellcode