Material Design 3 — это следующая эволюция Material Design. Он включает в себя обновленные темы, компоненты и функции персонализации Material You, такие как динамический цвет. Это обновление Material Design 2 , которое сочетается с новым визуальным стилем и системным пользовательским интерфейсом на Android 12 и более поздних версиях.
В этом руководстве основное внимание уделяется переходу из библиотеки Compose Material (androidx.compose.material) Jetpack в библиотеку Compose Material 3 (androidx.compose.material3) Jetpack .
Подходы
В общем , не следует использовать одновременно M2 и M3 в одном приложении в долгосрочной перспективе . Это связано с тем, что две системы дизайна и соответствующие библиотеки существенно различаются с точки зрения дизайна UX/UI и реализации Compose.
Ваше приложение может использовать систему дизайна, например созданную с помощью Figma. В таких случаях мы также настоятельно рекомендуем вам или вашей команде разработчиков перенести его с M2 на M3, прежде чем начинать миграцию Compose. Нет смысла переносить приложение на M3, если его UX/UI-дизайн основан на M2.
Более того, ваш подход к миграции должен различаться в зависимости от размера, сложности и дизайна UX/UI вашего приложения. Это поможет вам минимизировать влияние на вашу кодовую базу. К миграции следует подходить поэтапно.
Когда мигрировать
Вам следует начать миграцию как можно скорее. Однако важно учитывать, находится ли ваше приложение в состоянии полностью перейти с M2 на M3. Прежде чем приступить к работе, следует изучить некоторые сценарии блокирования :
Сценарий | Рекомендуемый подход |
---|---|
Нет блокировщиков | Начать поэтапную миграцию |
Компонент из М2 пока недоступен в М3. См. раздел «Компоненты и макеты» ниже. | Начать поэтапную миграцию |
Вы или ваша команда дизайнеров не перенесли систему дизайна приложения с M2 на M3. | Перенесите систему проектирования с M2 на M3, затем начните поэтапную миграцию. |
Даже если на вас влияют описанные выше сценарии, вам следует применить поэтапный подход к миграции, прежде чем фиксировать и выпускать обновление приложения. В этих случаях вы можете использовать M2 и M3 одновременно и постепенно отказываться от M2 при переходе на M3.
Поэтапный подход
Общие шаги к поэтапной миграции следующие:
- Добавьте зависимость M3 рядом с зависимостью M2.
- Добавьте версии M3 тем вашего приложения вместе с версиями M2 тем вашего приложения.
- Переносите отдельные модули, экраны или составные элементы в M3, в зависимости от размера и сложности вашего приложения (подробности см. в разделах ниже).
- После полного переноса удалите версии M2 тем вашего приложения.
- Удалите зависимость M2.
Зависимости
M3 имеет отдельный пакет и версию для M2:
М2
implementation "androidx.compose.material:material:$m2-version"
М3
implementation "androidx.compose.material3:material3:$m3-version"
Последние версии M3 смотрите на странице релизов Compose Material 3 .
Другие зависимости материалов за пределами основных библиотек M2 и M3 не изменились. Они используют сочетание пакетов и версий M2 и M3, но это не влияет на миграцию. Их можно использовать с M3 как есть:
Библиотека | Пакет и версия |
---|---|
Создание значков материалов | androidx.compose.material:material-icons-*:$m2-version |
Составление пульсации материала | androidx.compose.material:material-ripple:$m2-version |
Экспериментальные API
Некоторые API M3 считаются экспериментальными. В таких случаях вам необходимо согласиться на уровне функции или файла, используя аннотацию ExperimentalMaterial3Api
:
import androidx.compose.material3.ExperimentalMaterial3Api
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AppComposable() {
// M3 composables
}
Тематика
И в M2, и в M3 компонуемая тема называется MaterialTheme
но пакеты и параметры импорта различаются:
М2
import androidx.compose.material.MaterialTheme
MaterialTheme(
colors = AppColors,
typography = AppTypography,
shapes = AppShapes
) {
// M2 content
}
М3
import androidx.compose.material3.MaterialTheme
MaterialTheme(
colorScheme = AppColorScheme,
typography = AppTypography,
shapes = AppShapes
) {
// M3 content
}
Цвет
Цветовая система в М3 существенно отличается от М2. Количество цветовых параметров увеличилось, они имеют другие названия и по-разному сопоставляются с компонентами M3. В Compose это относится к классу M2 Colors
, классу M3 ColorScheme
и связанным функциям:
М2
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
}
М3
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
}
Учитывая значительные различия между цветовыми системами M2 и M3, разумного сопоставления параметров Color
не существует. Вместо этого используйте инструмент Material Theme Builder для создания цветовой схемы M3. Используйте цвета M2 в качестве основных исходных цветов в инструменте, который расширяется до тоновых палитр, используемых цветовой схемой M3. В качестве отправной точки рекомендуется использовать следующие сопоставления:
М2 | Конструктор тем материалов |
---|---|
primary | Начальный |
primaryVariant | вторичный |
secondary | Третичный |
surface или background | Нейтральный |
Вы можете скопировать значения шестнадцатеричного кода цвета для светлых и темных тем из инструмента и использовать их для реализации экземпляра M3 ColorScheme. Альтернативно, Material Theme Builder может экспортировать код Compose.
isLight
В отличие от класса M2 Colors
, класс M3 ColorScheme
не включает параметр isLight
. В общем, вам следует попытаться смоделировать все, что нуждается в этой информации, на уровне темы. Например:
М2
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
…
}
}
М3
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
…
}
}
Дополнительную информацию см. в руководстве «Системы индивидуального дизайна в Compose» .
Динамический цвет
Новой функцией M3 является динамический цвет . Вместо использования собственных цветов ColorScheme
M3 может использовать цвета обоев устройства на Android 12 и более поздних версиях, используя следующие функции:
Типография
Система типографики в M3 отличается от M2. Количество параметров оформления примерно одинаковое, но они имеют разные имена и по-разному сопоставляются с компонентами M3. В Compose это относится к классу Typography
M2 и классу Typography
M3:
М2
import androidx.compose.material.Typography
val AppTypography = Typography(
// M2 TextStyle parameters
)
М3
import androidx.compose.material3.Typography
val AppTypography = Typography(
// M3 TextStyle parameters
)
В качестве отправной точки рекомендуется использовать следующие сопоставления параметров TextStyle
:
М2 | М3 |
---|---|
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 |
Форма
Система форм в M3 отличается от M2. Количество параметров формы увеличилось, они называются по-другому и по-другому сопоставляются с компонентами M3. В Compose это относится к классу « Shapes
M2» и классу Shapes
M3»:
М2
import androidx.compose.material.Shapes
val AppShapes = Shapes(
// M2 Shape parameters
)
М3
import androidx.compose.material3.Shapes
val AppShapes = Shapes(
// M3 Shape parameters
)
В качестве отправной точки рекомендуется использовать следующие сопоставления параметров Shape
:
М2 | М3 |
---|---|
Н/Д | extraSmall |
small | small |
medium | medium |
large | large |
Н/Д | extraLarge |
Компоненты и макеты
Большинство компонентов и макетов из M2 доступны в M3. Однако есть некоторые недостающие, а также новые, которых не было в M2. Более того, некоторые компоненты M3 имеют больше вариаций, чем их эквиваленты в M2. В целом поверхности API M3 стараются быть как можно более похожими на свои ближайшие эквиваленты в M2.
Учитывая обновленные системы цвета, типографики и форм, компоненты M3 имеют тенденцию по-разному отображаться в соответствии с новыми значениями тем. Рекомендуется проверить каталог tokens в исходном коде Compose Material 3 как источник достоверных данных об этих сопоставлениях.
Хотя некоторые компоненты требуют особого внимания, в качестве отправной точки рекомендуется использовать следующие сопоставления функций:
Отсутствующие API :
М2 | М3 |
---|---|
androidx.compose.material.swipeable | Пока недоступно |
Заменены API :
М2 | М3 |
---|---|
androidx.compose.material.BackdropScaffold | Нет эквивалента M3, вместо этого перейдите на Scaffold или BottomSheetScaffold |
androidx.compose.material.BottomDrawer | Нет эквивалента M3, вместо этого перейдите на ModalBottomSheet |
Переименованные API :
Все остальные API :
Ознакомьтесь с новейшими компонентами и макетами M3 в справочном обзоре API Compose Material 3 и следите за новыми и обновленными API на странице выпусков .
Подмости, закусочные и навигационный ящик
Леса в M3 отличаются от M2. И в M2, и в M3 основной составной макет называется Scaffold
но пакеты и параметры импорта различаются:
М2
import androidx.compose.material.Scaffold
Scaffold(
// M2 scaffold parameters
)
М3
import androidx.compose.material3.Scaffold
Scaffold(
// M3 scaffold parameters
)
Scaffold
M2 содержит параметр backgroundColor
containerColor
который теперь называетсяContainerColor в Scaffold
M3:
М2
import androidx.compose.material.Scaffold
Scaffold(
backgroundColor = …,
content = { … }
)
М3
import androidx.compose.material3.Scaffold
Scaffold(
containerColor = …,
content = { … }
)
Класс M2 ScaffoldState
больше не существует в M3, поскольку он содержит параметр drawerState
, который больше не нужен. Чтобы отобразить закусочные с помощью M3 Scaffold
, используйте вместо этого SnackbarHostState
:
М2
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(…)
}
}
)
М3
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(…)
}
}
)
Все параметры drawer*
из Scaffold
M2 были удалены из Scaffold
M3. К ним относятся такие параметры, как drawerShape
и drawerContent
. Чтобы отобразить ящик с помощью M3 Scaffold
, используйте вместо этого составной ящик навигации, например ModalNavigationDrawer
:
М2
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()
}
}
)
М3
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()
}
}
)
}
)
Верхняя панель приложений
Верхние панели приложений в M3 отличаются от панелей в M2. И в M2, и в M3 основная компонуемая верхняя панель приложения называется TopAppBar
но пакеты и параметры импорта различаются:
М2
import androidx.compose.material.TopAppBar
TopAppBar(…)
М3
import androidx.compose.material3.TopAppBar
TopAppBar(…)
Рассмотрите возможность использования M3 CenterAlignedTopAppBar
, если вы ранее центрировали контент внутри M2 TopAppBar
. Также полезно знать о MediumTopAppBar
и LargeTopAppBar
.
Верхние панели приложений M3 содержат новый параметр scrollBehavior
, обеспечивающий различные функции при прокрутке класса TopAppBarScrollBehavior
, например изменение высоты. Это работает в сочетании с прокруткой контента через Modifer.nestedScroll
. Это стало возможным в TopAppBar
M2 путем изменения параметра elevation
вручную:
М2
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) { … }
}
)
М3
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 { … }
}
)
Нижняя навигация/Панель навигации
Нижняя навигация в M2 была переименована в панель навигации в M3. В M2 есть составные элементы BottomNavigation
и BottomNavigationItem
, а в M3 — составные элементы NavigationBar
и NavigationBarItem
:
М2
import androidx.compose.material.BottomNavigation
import androidx.compose.material.BottomNavigationItem
BottomNavigation {
BottomNavigationItem(…)
BottomNavigationItem(…)
BottomNavigationItem(…)
}
М3
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
NavigationBar {
NavigationBarItem(…)
NavigationBarItem(…)
NavigationBarItem(…)
}
Кнопки, кнопки со значками и FAB
Кнопки, кнопки со значками и кнопки плавающих действий (FAB) в M3 отличаются от кнопок в M2. M3 включает в себя все компоненты кнопок M2:
М2
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(…)
М3
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 также включает новые варианты кнопок. Ознакомьтесь с ними в справочном обзоре API Compose Material 3 .
Выключатель
Переключатель в М3 отличается от М2. И в M2, и в M3 компонуемый переключатель называется Switch
, но пакеты импорта различаются:
М2
import androidx.compose.material.Switch
Switch(…)
М3
import androidx.compose.material3.Switch
Switch(…)
Поверхности и высота
Системы поверхности и высот в M3 отличаются от M2. В M3 есть два типа возвышений:
- Высота тени (отбрасывает тень, как и M2)
- Тональное возвышение (накладывает цвет, новое для M3)
В Compose это относится к функции M2 Surface
и функции M3 Surface
:
М2
import androidx.compose.material.Surface
Surface(
elevation = …
) { … }
М3
import androidx.compose.material3.Surface
Surface(
shadowElevation = …,
tonalElevation = …
) { … }
Вы можете использовать значения Dp
elevation
в M2 как shadowElevation
, так и для tonalElevation
в M3, в зависимости от предпочтений дизайна UX/UI. Surface
является составной основой большинства компонентов, поэтому составные компоненты могут также предоставлять параметры высоты, которые необходимо перенести таким же образом.
Тональное возвышение в M3 заменяет концепцию наложения возвышений в темных темах M2. В результате ElevationOverlay
и LocalElevationOverlay
не существуют в M3, а LocalAbsoluteElevation
в M2 изменилась на LocalAbsoluteTonalElevation
в M3.
Акцент и содержание альфа
Акцент в М3 существенно отличается от М2. В M2 акцент был сделан на использовании цветов с определенными значениями альфа для различения контента, такого как текст и значки. В M3 теперь есть несколько разных подходов:
- Использование цветов вместе с вариантами цветов из расширенной цветовой системы M3.
- Использование разной толщины шрифта для текста.
В результате ContentAlpha
и LocalContentAlpha
не существуют в M3, и их необходимо заменить.
В качестве отправной точки рекомендуется использовать следующие сопоставления:
М2 | М3 |
---|---|
onSurface с ContentAlpha.high | onSurface в целом, FontWeight.Medium — FontWeight.Black для текста |
onSurface с ContentAlpha.medium | onSurfaceVariant в целом, FontWeight.Thin — FontWeight.Normal для текста |
onSurface с ContentAlpha.disabled | onSurface.copy(alpha = 0.38f) |
Вот пример выделения значков в M2 и M3:
М2
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(…)
}
М3
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(…)
}
Вот примеры выделения текста в M2 и M3:
М2
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(…)
}
М3
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
)
}
Фоны и контейнеры
Фоны в M2 называются контейнерами в M3. В общем, вы можете заменить параметры background*
в M2 на container*
в M3, используя те же значения. Например:
М2
Badge(
backgroundColor = MaterialTheme.colors.primary
) { … }
М3
Badge(
containerColor = MaterialTheme.colorScheme.primary
) { … }
Полезные ссылки
Чтобы узнать больше о переходе с M2 на M3 в Compose, обратитесь к следующим дополнительным ресурсам.
Документы
Примеры приложений
- Пример приложения «Ответ» M3
- Пример приложения Jetchat, миграция с M2 на M3
- Пример приложения Jetnews: миграция с M2 на M3
- Теперь в приложении Android M3 Hero: модуль core-designsystem
Видео
Ссылка на API и исходный код
{% дословно %}Рекомендуется для вас
- Примечание. Текст ссылки отображается, когда JavaScript отключен.
- Material Design 2 в Compose
- Material Design 3 в Compose
- Системы индивидуального дизайна в Compose