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

Material Design 3 to kolejna ewolucja Material Design. Obejmuje 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 na Androidzie 12 i nowszym.

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

Podejścia

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

Aplikacja może korzystać z systemu projektowania, np. utworzonego za pomocą Figmy. W takich przypadkach zdecydowanie zalecamy, aby Ty lub Twój zespół projektowy przenieśli go z M2 do M3 przed rozpoczęciem migracji do Compose. Nie ma sensu przenosić aplikacji do 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 UX/UI aplikacji. Dzięki temu zminimalizujesz wpływ na bazę kodu. Migrację należy przeprowadzać etapami.

Kiedy przeprowadzić migrację

Migrację należy rozpocząć jak najszybciej. Warto jednak zastanowić się, czy Twoja aplikacja jest w stanie w pełni przejść z M2 na M3. Zanim zaczniesz, rozważ te scenariusze blokujące:

Scenariusz Zalecane działania
Brak czynników blokujących Rozpocznij migrację etapową
Komponent z M2 nie jest jeszcze dostępny w M3. Więcej informacji znajdziesz w sekcji Komponenty i układy poniżej. Rozpocznij migrację etapową
Ty lub Twój zespół projektowy nie przenieśliście systemu projektowania aplikacji z M2 na M3. Przenieś system projektowania z M2 na M3, a potem rozpocznij migrację etapową.

Nawet jeśli dotyczą Cię powyższe scenariusze, przed wprowadzeniem i opublikowaniem aktualizacji aplikacji warto zastosować podejście etapowe. W takich przypadkach używasz modeli M2 i M3 równolegle i stopniowo wycofujesz model M2, przechodząc na model M3.

Podejście etapowe

Ogólne etapy migracji etapowej są następujące:

  1. Dodaj zależność M3 obok zależności M2.
  2. Dodaj wersje M3 motywów aplikacji obok wersji M2 motywów aplikacji.
  3. Przenieś poszczególne moduły, ekrany lub komponenty do M3 w zależności od rozmiaru i złożoności aplikacji (szczegółowe informacje znajdziesz w sekcjach poniżej).
  4. Po pełnej migracji usuń wersje M2 motywów aplikacji.
  5. Usuń zależność M2.

Zależności

M3 ma osobny pakiet i wersję niż M2:

M2

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

M3

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

Najnowsze wersje M3 znajdziesz na stronie z informacjami o wersjach Compose Material 3.

Zależności od innych materiałów poza głównymi bibliotekami M2 i M3 nie uległy zmianie. Używają one różnych pakietów i wersji M2 i M3, ale nie ma to wpływu na migrację. Można ich używać w M3 w takiej postaci:

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

Eksperymentalne interfejsy API

Niektóre interfejsy API M3 są uznawane 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

W przypadku M2 i M3 funkcja kompozycyjna motywu 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) i M3 (po prawej).

System kolorów w M3 znacznie różni się od tego w M2. Liczba parametrów koloru wzrosła, mają one różne nazwy i inaczej mapują się na komponenty 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 znaczące różnice między systemami kolorów M2 i M3 nie ma rozsądnego mapowania parametrów Color. Zamiast tego użyj narzędzia do tworzenia motywów Material, aby wygenerować schemat kolorów M3. Używaj kolorów M2 jako podstawowych kolorów źródłowych w narzędziu, które rozszerza je na palety tonalne używane przez schemat kolorów M3. Jako punkt wyjścia zalecamy te mapowania:

M2 Kreator motywów Material Design
primary Podstawowy
primaryVariant Secondary
secondary Trzeciorzędny
surface lub background Nie mam zdania
których narzędzia używają w schemacie kolorów M3.
Kolory M2 używane w kreatorze motywów Material do generowania schematu kolorów M3
Rysunek 2. Kolory M2 aplikacji Jetchat użyte w Kreatorze motywów Material do wygenerowania schematu kolorów M3.

Możesz skopiować wartości szesnastkowe kodów kolorów dla motywów jasnego i ciemnego z narzędzia i użyć ich do wdrożenia instancji M3 ColorScheme. Możesz też wyeksportować kod Compose za pomocą narzędzia Material Theme Builder.

isLight

W przeciwieństwie do klasy M2 Colors klasa M3 ColorScheme nie zawiera parametru isLight. Zasadniczo staraj się modelować wszystko, co wymaga tych informacji, na poziomie motywu. Na 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

Nową funkcją M3 jest dynamiczny kolor. Zamiast używać niestandardowych kolorów, M3 ColorScheme może korzystać z kolorów tapety urządzenia na Androidzie 12 i nowszym, używając 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 typografii w M3 różni się od tego w M2. Liczba parametrów typografii jest mniej więcej taka sama, ale mają one inne nazwy i inaczej są mapowane na komponenty M3. W Compose dotyczy to klas M2 Typography i 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
)

Jako punkt wyjścia zalecamy te mapowania 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) i M3 (po prawej)

System kształtów w M3 różni się od tego w M2. Liczba parametrów kształtu wzrosła, mają one inne nazwy i inaczej są mapowane na komponenty M3. W przypadku tworzenia wiadomości dotyczy to klas M2 Shapes i 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
)

Jako punkt wyjścia zalecamy te mapowania 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 układów z M2 jest dostępna w M3. Brakuje jednak niektórych z nich, a pojawiają się nowe, których nie było w M2. Ponadto niektóre komponenty M3 mają więcej wariantów niż ich odpowiedniki w M2. Ogólnie rzecz biorąc, interfejsy M3 API są jak najbardziej podobne do swoich odpowiedników w M2.

Ze względu na zaktualizowane systemy kolorów, typografii i kształtów komponenty M3 są zwykle inaczej mapowane na nowe wartości motywu. Warto zapoznać się z katalogiem tokenów w kodzie źródłowym Compose Material 3, aby uzyskać informacje o tych mapowaniach.

Niektóre komponenty wymagają szczególnej uwagi, ale jako punkt wyjścia zalecamy te mapowania 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 przeprowadź migrację do ModalBottomSheet

Interfejsy API, których nazwy zostały zmienione:

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 pozostałe 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 przeglądzie interfejsu Compose Material 3 API. Nowe i zaktualizowane interfejsy API znajdziesz na stronie z informacjami o wersjach.

Scaffold, snackbary i panel nawigacji

Porównanie platform M2 i M3 z snackbarami i panelem nawigacyjnym
Rysunek 5. Platforma M2 z snackbarem i panelem nawigacyjnym (po lewej) w porównaniu z platformą M3 z snackbarem i panelem nawigacyjnym (po prawej).

Platforma w M3 różni się od platformy w M2. W przypadku M2 i M3 główny układ kompozycyjny ma nazwę Scaffold, ale pakiety importu i parametry są różne:

M2

import androidx.compose.material.Scaffold

Scaffold(
    // M2 scaffold parameters
)

M3

import androidx.compose.material3.Scaffold

Scaffold(
    // M3 scaffold parameters
)

Parametr backgroundColor w M2 Scaffold 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óry nie jest już potrzebny. Aby wyświetlać paski z Scaffold w Materialu 3, 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*Scaffold M2 zostały usunięte z Scaffold M3. Obejmują one parametry takie jak drawerShapedrawerContent. Aby wyświetlić panel z elementem Scaffold w stylu M3, użyj funkcji kompozycyjnej panelu nawigacji, np. 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 platform M2 i M3 z górnym paskiem aplikacji i przewijaną listą
Rysunek 6. M2 scaffold with top app bar and scrolled list (left) versus M3 scaffold with top app bar and scrolled list (right)

Górne paski aplikacji w M3 różnią się od tych w M2. W przypadku M2 i M3 główny komponent kompozycyjny górnego paska aplikacji ma nazwę TopAppBar, ale pakiety importu i parametry różnią się:

M2

import androidx.compose.material.TopAppBar

TopAppBar()

M3

import androidx.compose.material3.TopAppBar

TopAppBar()

Jeśli wcześniej wyśrodkowywałeś(-aś) treści w przypadku M2 TopAppBar, rozważ użycie M3 CenterAlignedTopAppBar. Warto też znać MediumTopAppBarLargeTopAppBar.

Górne paski aplikacji M3 zawierają nowy parametr scrollBehavior, który zapewnia różne funkcje podczas przewijania klasy TopAppBarScrollBehavior, np. zmianę wysokości. Działa to w połączeniu z przewijaniem treści za pomocą Modifer.nestedScroll. W M2 TopAppBar było to możliwe dzięki ręcznej zmianie parametru 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 nawigacji u dołu w M2 i paska nawigacyjnego w M3
Rysunek 7. Nawigacja u dołu ekranu M2 (po lewej) i pasek nawigacyjny M3 (po prawej).

Dolna nawigacja w M2 została w M3 zmieniona na pasek nawigacyjny. W module M2 znajdują się funkcje kompozycyjne BottomNavigationBottomNavigationItem, a w module M3 – funkcje kompozycyjne 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 ikonami i FAB

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

Przyciski, przyciski z ikonami i pływające przyciski polecenia w M3 różnią się od tych w M2. M3 zawiera wszystkie komponenty 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 Compose Material 3 API.

Przełącz

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

Przełącznik w M3 różni się od tego w M2. W przypadku M2 i M3 komponent przełącznika 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 wysokości powierzchni M2 i M3 w jasnym i ciemnym motywie
Rysunek 10. Wysokość powierzchni M2 w porównaniu z wysokością powierzchni 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 są 2 rodzaje wzniesień:

  • Wysokość cienia (rzuca cień, tak samo jak M2)
  • Podniesienie tonalne (nakładanie koloru, nowość w M3)

W przypadku tworzenia wiadomości dotyczy to funkcji M2 Surface i M3 Surface:

M2

import androidx.compose.material.Surface

Surface(
    elevation = 
) {  }

M3

import androidx.compose.material3.Surface

Surface(
    shadowElevation = ,
    tonalElevation = 
) {  }

W przypadku obu wartości shadowElevationtonalElevation w M3 możesz użyć wartości elevation Dp w M2, w zależności od preferencji dotyczących projektu UX/UI. Surface to kompozycja bazowa większości komponentów, więc kompozycje komponentów mogą też udostępniać parametry wysokości, które musisz przenieść w ten sam sposób.

W M3 tonalne podniesienie zastępuje koncepcję nakładek podniesienia w ciemnych motywach M2 . W związku z tym w M3 nie ma funkcji ElevationOverlayLocalElevationOverlay, a funkcja LocalAbsoluteElevation w M2 została zmieniona na LocalAbsoluteTonalElevation w M3.

Podkreślenie i przezroczystość treści

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

Nacisk w M3 jest znacznie inny niż w M2. W M2 nacisk polegał na używaniu kolorów on z określonymi wartościami alfa, aby odróżnić treści takie jak tekst i ikony. W M3 dostępne są teraz 2 różne podejścia:

  • Używaj kolorów on wraz z ich wariantami z rozszerzonego systemu kolorów M3.
  • Używanie różnych grubości czcionki w tekście.

W związku z tym w M3 nie ma znaków ContentAlphaLocalContentAlpha, więc trzeba je zastąpić.

Na początek zalecamy te skróty:

M2 M3
onSurface w aplikacji ContentAlpha.high onSurface – ogólnie FontWeight.Medium – FontWeight.Black w przypadku tekstu.
onSurface w aplikacji ContentAlpha.medium onSurfaceVariant – ogólnie FontWeight.Thin – FontWeight.Normal w przypadku tekstu;
onSurface w aplikacji ContentAlpha.disabled onSurface.copy(alpha = 0.38f)

Oto przykład wyróżnienia ikony w M2 i 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 przypadku poziomó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ą nazwanymi kontenerami w M3. Ogólnie rzecz biorąc, możesz zastąpić parametry background* w M2 parametrami container* w M3, używając tych samych wartości. Na przykład:

M2

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

M3

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

Więcej informacji o migracji z M2 do M3 w Compose znajdziesz w tych dodatkowych materiałach.

Dokumenty

Przykładowe aplikacje

Filmy

Dokumentacja API i kod źródłowy