Migracja z Material 2 do Material 3 w sekcji Utwórz

Material Design 3 to kolejna wersja Material Design. Obejmuje ona zaktualizowane motywy, komponenty i funkcje personalizacji Material You, takie jak dynamiczne kolory. Jest to aktualizacja Material Design 2, która jest spójna z nowym stylem wizualnym i interfejsem systemu w Androidzie 12 lub nowszym.

Ten przewodnik dotyczy migracji z biblioteki Jetpack Compose Material (androidx.compose.material) do biblioteki Jetpack Compose Material 3 (androidx.compose.material3).

Podejścia

Ogólnie nie należy długotrwale używać w jednej aplikacji zarówno M2, jak i M3. Wynika to z tego, że oba systemy projektowania i odpowiednie biblioteki różnią się znacznie pod względem projektowania UX/UI i implementacji Compose.

Aplikacja może korzystać z systemu projektowania, np. utworzonego w programie Figma. W takich przypadkach zdecydowanie zalecamy, aby Ty lub Twój zespół projektantów przeprowadzili migrację z M2 do M3 przed rozpoczęciem migracji w Compose. Nie ma sensu przekształcanie aplikacji w M3, jeśli jej projekt UX/UI jest oparty na M2.

Ponadto podejście do migracji powinno się różnić w zależności od rozmiaru, złożoności i projektu interfejsu użytkownika aplikacji. Pozwoli to zminimalizować wpływ na kod źródłowy. Migrację należy przeprowadzić etapami.

Kiedy przeprowadzić migrację

Migrację należy rozpocząć jak najszybciej. Należy jednak wziąć pod uwagę, czy Twoja aplikacja jest w stanie w pełni przejść z M2 na M3. Zanim zaczniesz, sprawdź, czy nie występują blokujące scenariusze:

Scenariusz Zalecane działania
Brak blokujących Rozpocznij migrację w etapach
Komponent z M2 nie jest jeszcze dostępny w M3. Zapoznaj się z sekcją Komponenty i układy poniżej. Rozpocznij migrację w etapach
Ty lub Twój zespół projektantów nie przeprowadziliście migracji systemu projektowania aplikacji z M2 na M3 Przeniesienie systemu projektowania z M2 do M3, a następnie rozpoczęcie migracji etapowej

Nawet jeśli któryś z wymienionych powyżej scenariuszy Cię dotyczy, przed przesłaniem i opublikowaniem aktualizacji aplikacji powinieneś przeprowadzić migrację w etapach. W takich przypadkach możesz używać jednocześnie wersji M2 i M3, a podczas migracji do wersji M3 stopniowo wycofywać wersję M2.

Metoda stopniowa

Ogólne etapy migracji w etapach:

  1. Dodaj zależność M3 obok zależności M2.
  2. Dodaj wersje M3 motywów aplikacji obok wersji M2 motywów aplikacji.
  3. Przeniesienie poszczególnych modułów, ekranów lub komponentów na M3 w zależności od rozmiaru i złożoności aplikacji (szczegółowe informacje znajdziesz w sekcji poniżej).
  4. Po zakończeniu migracji usuń wersje M2 motywów aplikacji.
  5. Usuń zależność M2.

Zależności

M3 ma oddzielny pakiet i wersję od M2:

M2

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

M3

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

Najnowsze wersje M3 znajdziesz na stronie z wersjami Compose Material 3.

Pozostałe zależności materiałów spoza głównych bibliotek M2 i M3 nie uległy zmianie. Używają one pakietów i wersji M2 i M3, ale nie ma to wpływu na migrację. Można ich używać w M3 bez zmian:

Biblioteka Pakiet i wersja
Tworzenie ikon Material Design androidx.compose.material:material-icons-*:$m2-version
Tworzenie efektu fali androidx.compose.material:material-ripple:$m2-version

Eksperymentalne interfejsy API

Niektóre interfejsy M3 są uważane za eksperymentalne. W takich przypadkach musisz wyrazić zgodę na poziomie funkcji lub pliku, używając adnotacji ExperimentalMaterial3Api:

import androidx.compose.material3.ExperimentalMaterial3Api

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

Motywy

Zarówno w M2, jak i w M3 kompozyt tematyczny ma nazwę MaterialTheme, ale pakiety importu i parametry różnią się:

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
}

Kolor

Porównanie systemów kolorów M2 i M3
Rysunek 1. System kolorów M2 (po lewej) a system kolorów M3 (po prawej).

System kolorów w M3 różni się znacznie od tego w M2. Liczba parametrów kolorów wzrosła, mają one różne nazwy i różnie mapowania do komponentów M3. W Compose dotyczy to klasy M2 Colors, klasy M3 ColorScheme i powiązanych funkcji:

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
}

Ze względu na znaczne różnice między systemami kolorów M2 i M3 nie ma odpowiedniego mapowania dla parametrów Color. Zamiast tego użyj narzędzia do tworzenia motywów Material Design, aby wygenerować schemat kolorów M3. Użyj kolorów M2 jako podstawowych kolorów źródłowych w narzędziu, które zostaną rozszerzone do palety barw używanych przez schemat kolorów M3. Na początek zalecamy użycie tych mapowań:

M2 Material Theme Builder
primary Główny
primaryVariant Secondary
secondary Tertiary
surface lub background Nie mam zdania
Kolory M2 używane w Kreatorze motywów Material do wygenerowania schematu kolorów M3
Rysunek 2. Kolory M2 z Jetchat użyte w Material Theme Builder do wygenerowania schematu kolorów M3.

Możesz skopiować z tego narzędzia wartości szesnastkowych kodów kolorów dla motywów jasnych i ciemnych, a następnie użyć ich do zaimplementowania wystąpienia klasy M3 ColorScheme. Możesz też wyeksportować kod Compose za pomocą Kreatora motywów Material.

isLight

W przeciwieństwie do klasy M2 Colors klasa M3 ColorScheme nie zawiera parametru isLight. Ogólnie rzecz biorąc, należy spróbować modelować wszystko, co wymaga tych informacji na poziomie motywu. Przykład:

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

Więcej informacji znajdziesz w przewodniku po niestandardowych systemach projektowania w Compose.

Kolory dynamiczne

Nowością w M3 jest dynamiczny kolor. Zamiast używać niestandardowych kolorów, M3 ColorScheme może korzystać z kolorów tapety na urządzeniu z Androidem w wersji 12 lub nowszej, korzystając z tych funkcji:

Typografia

Porównanie systemów typograficznych M2 i M3
Rysunek 3. System typograficzny M3 (po lewej) w porównaniu z systemem typograficznym M2 (po prawej)

System typograficzny w M3 różni się od tego w M2. Liczba parametrów typograficznych jest mniej więcej taka sama, ale mają one różne nazwy i różnie mapowania na komponenty M3. W Compose dotyczy to klasy M2 Typography i klasy 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
)

Na początek zalecamy użycie tych mapowań parametrów TextStyle:

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

Kształt

Porównanie systemów kształtów M2 i M3
Rysunek 4. System kształtów M2 (po lewej) a system kształtów M3 (po prawej)

System kształtów w M3 różni się od tego w M2. Zwiększono liczbę parametrów kształtu, zmieniono ich nazwy i sposób mapowania na komponenty M3. W edytorze dotyczy to klasy M2 Shapes i klasy 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
)

Na początek zalecamy użycie tych mapowań parametrów Shape:

M2 M3
Nie dotyczy extraSmall
small small
medium medium
large large
Nie dotyczy extraLarge

Komponenty i układy

Większość komponentów i schematów z M2 jest dostępna w M3. Brakuje jednak niektórych z nich, a pojawiły się nowe, których nie było w M2. Co więcej, niektóre komponenty M3 mają więcej wersji niż ich odpowiedniki w M2. Zasadniczo interfejsy API M3 starają się być jak najbardziej podobne do ich odpowiedników w M2.

Ze względu na zaktualizowane systemy kolorów, typografii i kształtów komponenty M3 są zwykle mapowane inaczej do nowych wartości motywów. Warto sprawdzić katalog z tokenami w kodzie źródłowym Compose Material 3, aby uzyskać informacje o tych mapowaniach.

Chociaż niektóre komponenty wymagają szczególnej uwagi, jako punkt wyjścia zalecamy użycie tych map funkcji:

Brakujące interfejsy API:

M2 M3
androidx.compose.material.swipeable Jeszcze niedostępne

Zastąpione interfejsy API:

M2 M3
androidx.compose.material.BackdropScaffold Brak odpowiednika M3, zamiast tego przeprowadź migrację do Scaffold lub BottomSheetScaffold
androidx.compose.material.BottomDrawer Brak odpowiednika M3, zamiast tego przejdź na ModalBottomSheet

Zmiana nazw interfejsów API:

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

Wszystkie inne interfejsy 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

Najnowsze komponenty i układy M3 znajdziesz w omówieniu interfejsu Compose Material 3 API. Nowe i zaktualizowane interfejsy API znajdziesz na stronie z wersjami API.

szkielet, paski narzędzi i panel nawigacji

Porównanie szkieletu M2 i M3 z paskiem szybkiego dostępu i szufladą nawigacyjną
Rysunek 5. Szkielet M2 ze snackbarem i drawerem nawigacji (po lewej) w porównaniu ze szkieletem M3 ze snackbarem i drawerem nawigacji (po prawej).

Szablon w M3 różni się od tego w M2. Zarówno w M2, jak i w M3 główny komponent układu ma nazwę Scaffold, ale pakiety importu i parametry różnią się:

M2

import androidx.compose.material.Scaffold

Scaffold(
    // M2 scaffold parameters
)

M3

import androidx.compose.material3.Scaffold

Scaffold(
    // M3 scaffold parameters
)

W M2 Scaffold parametr backgroundColor ma teraz nazwę containerColor w M3 Scaffold:

M2

import androidx.compose.material.Scaffold

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

M3

import androidx.compose.material3.Scaffold

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

Klasa M2 ScaffoldState nie istnieje już w M3, ponieważ zawiera parametr drawerState, którego nie trzeba już używać. Aby wyświetlać paski informacji w ramach Scaffold M3, użyj 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(…)
        }
    }
)

Wszystkie parametry drawer* z wersji M2 Scaffold zostały usunięte z wersji M3 Scaffold. Obejmują one parametry takie jak drawerShapedrawerContent. Aby wyświetlić panel nawigacji z elementem M3 Scaffold, użyj kompozytu panelu nawigacji, takiego jak 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()
                }
            }
        )
    }
)

Górny pasek aplikacji

Porównanie szkieletu M2 i M3 z górnym paskiem aplikacji i przewijaną listą
Rysunek 6. Szkielet M2 z górnym paskiem aplikacji i przewiniętą listą (po lewej) a szkielet M3 z górnym paskiem aplikacji i przewiniętą listą (po prawej)

Paski aplikacji w M3 różnią się od tych w M2. Zarówno w M2, jak i w M3 główny element składany paska aplikacji u góry ma nazwę TopAppBar, ale importowane pakiety i parametry różnią się:

M2

import androidx.compose.material.TopAppBar

TopAppBar(…)

M3

import androidx.compose.material3.TopAppBar

TopAppBar(…)

Jeśli wcześniej treści były wyśrodkowane w ramach formatu M2 TopAppBar, rozważ użycie formatu M3 CenterAlignedTopAppBar. Warto też zapoznać się z artykułami MediumTopAppBarLargeTopAppBar.

Górne paski aplikacji M3 zawierają nowy parametr scrollBehavior, który zapewnia różne funkcje podczas przewijania w klasie TopAppBarScrollBehavior, np. zmianę wysokości. Funkcja ta działa w połączeniu z przewijaniem treści za pomocą Modifer.nestedScroll. W M2 TopAppBar można to zrobić, ręcznie zmieniając parametr 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 { … }
    }
)

Dolna nawigacja / Pasek nawigacyjny

Porównanie paska nawigacyjnego M2 i paska nawigacyjnego M3
Rysunek 7. Pasek nawigacyjny M2 (po lewej) a pasek nawigacyjny M3 (po prawej).

Pasek dolny w M2 został w M3 przemianowany na pasek nawigacyjny. W wersji M2 dostępne są komponenty BottomNavigationBottomNavigationItem, a w wersji M3 – komponenty NavigationBarNavigationBarItem:

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

przyciski, przyciski z ikoną i przyciski typu FAB;

Porównanie przycisków M2 i M3
Rysunek 8. Przyciski M2 (po lewej) i M3 (po prawej)

Przyciski, przyciski z ikoną i pływające przyciski polecenia w M3 są inne niż w M2. M3 zawiera wszystkie komponenty kompozytowe przycisku 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 zawiera też nowe warianty przycisków. Znajdziesz je w omówieniu interfejsu API Compose Material3.

Przełącz

Porównanie przełączników M2 i M3
Rysunek 9. Przełącznik M2 (po lewej) w porównaniu z przełącznikiem M3 (po prawej).

Przełącznik w M3 różni się od M2. W obu wersjach (M2 i M3) kompozyt na przełącznik ma nazwę Switch, ale pakiety importu różnią się:

M2

import androidx.compose.material.Switch

Switch(…)

M3

import androidx.compose.material3.Switch

Switch(…)

Powierzchnie i wysokość

Porównanie rzędnej powierzchni M2 i M3 w jasnym i ciemnym trybie
Rysunek 10. Porównanie wysokości powierzchni M2 i M3 w jasnym (po lewej) i ciemnym (po prawej) motywie.

Systemy powierzchni i wysokości w M3 różnią się od tych w M2. W M3 występują 2 typy wzniesienia:

  • Shadow elevation (casts a shadow, same as M2)
  • tonalne podniesienie (nakłada kolor, nowość w M3).

W składaniu dotyczy to funkcji M2 Surface i funkcji M3 Surface:

M2

import androidx.compose.material.Surface

Surface(
    elevation = …
) { … }

M3

import androidx.compose.material3.Surface

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

W M2 możesz użyć wartości elevation Dp zarówno w przypadku shadowElevation, jak i tonalElevation w M3, w zależności od preferencji w zakresie wrażeń użytkownika i interfejsu. Surface jest komponentem podstawowym dla większości komponentów, więc komponenty te mogą również udostępniać parametry wysokości, które musisz przenieść w taki sam sposób.

Podwyższenie tonalne w M3 zastępuje koncepcję nakładek podwyższenia w ciemnych motywach M2 . W rezultacie w M3 nie występują parametry ElevationOverlayLocalElevationOverlay, a parametry LocalAbsoluteElevation w M2 zostały zmienione na LocalAbsoluteTonalElevation w M3.

akcentowanie i przejrzystość treści.

Porównanie ikony i podkreślenia tekstu w M2 i M3
Rysunek 11. Ikona i wyróżnienie tekstu M2 (po lewej) w porównaniu z ikoną i wyróżnieniem tekstu M3 (po prawej)

Nacisk w M3 jest znacznie inny niż w M2. W M2 nacisk kładziony był na używaniu kolorów z określonymi wartościami alfa, aby odróżniać elementy treści, takie jak tekst i ikony. W M3 można teraz zastosować kilka różnych podejść:

  • Używanie kolorów na wraz z ich wariantami z rozszerzonego systemu kolorów M3.
  • Używanie różnych grubości czcionek.

W związku z tym elementy ContentAlphaLocalContentAlpha nie występują w pliku M3 i muszą zostać zastąpione.

Jako punkt wyjścia zalecamy użycie tych mapowań:

M2 M3
onSurface w aplikacji ContentAlpha.high onSurface ogólnie FontWeight.MediumFontWeight.Black dla tekstu
onSurface w aplikacji ContentAlpha.medium onSurfaceVariant ogólnie FontWeight.ThinFontWeight.Normal dla tekstu
onSurface w aplikacji ContentAlpha.disabled onSurface.copy(alpha = 0.38f)

Oto przykład podkreślenia ikony w wersji M2 w porównaniu z 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(…)
}

Oto przykłady wyróżnienia tekstu w M2 i 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
    )
}

Tła i kontenery

Tła w M2 są nazwane kontenerami w M3. Ogólnie możesz zastąpić parametry background* w M2 parametrami container* w M3, używając tych samych wartości. Przykład:

M2

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

M3

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

Więcej informacji o przechodzeniu z wersji M2 na M3 w Compose znajdziesz w tych dodatkowych materiałach.

Dokumenty

Przykładowe aplikacje

Filmy

Dokumentacja i kod źródłowy interfejsu API