Jetpack Compose предлагает реализацию Material You и Material 3 Expressive – следующего поколения Material Design. M3 Expressive – это расширение Material Design 3, включающее основанные на исследованиях обновления тем, компонентов, анимации, типографики и других элементов. Все они призваны помочь вам создавать привлекательные и удобные продукты, которые понравятся пользователям. Также поддерживаются функции персонализации Material You, например динамические цвета. M3 Expressive дополняет визуальный стиль и системный интерфейс Android 16.
Ниже показано, как реализовать Material Design 3 на примере примера приложения Reply. Пример приложения Reply полностью основан на Material Design 3.
Зависимость
Чтобы начать использовать Material 3 в приложении Compose, добавьте зависимость Compose Material 3 в файлы build.gradle:
implementation "androidx.compose.material3:material3:$material3_version"
После добавления зависимости вы можете начать добавлять в приложения системы Material Design, в том числе цвета, типографику и формы.
Экспериментальные API
Некоторые API M3 считаются экспериментальными. В таких случаях нужно включить эту функцию на уровне функции или файла с помощью аннотации ExperimentalMaterial3Api:
// import androidx.compose.material3.ExperimentalMaterial3Api @Composable fun AppComposable() { // M3 composables }
Тематическое оформление Material Design
Тема M3 содержит следующие подсистемы: цветовая схема, типографика и формы. Если вы измените эти значения, они автоматически отразятся в компонентах M3, которые вы используете для создания приложения.
В Jetpack Compose эти концепции реализованы с помощью функции M3 MaterialTheme
composable:
MaterialTheme( colorScheme = /* ... typography = /* ... shapes = /* ... ) { // M3 app content }
Чтобы задать тему для контента приложения, определите цветовую схему, типографику и формы, которые будут использоваться в приложении.
Цветовая схема
Основа цветовой схемы – набор из пяти основных цветов. Каждый из этих цветов относится к тональной палитре из 13 тонов, которые используются компонентами Material 3. Например, вот цветовая схема для светлой темы для Ответить:
Подробнее о цветовой схеме и ролях цветов…
Как сгенерировать цветовые схемы
Вы можете создать собственную палитру ColorScheme вручную, но часто проще сгенерировать ее на основе исходных цветов бренда. Это можно сделать с помощью инструмента Material Theme Builder, а также экспортировать код для создания тем Compose. Будут созданы следующие файлы:
Color.ktсодержит цвета темы со всеми ролями, определенными для светлой и темной темы.
val md_theme_light_primary = Color(0xFF476810) val md_theme_light_onPrimary = Color(0xFFFFFFFF) val md_theme_light_primaryContainer = Color(0xFFC7F089) // .. // .. val md_theme_dark_primary = Color(0xFFACD370) val md_theme_dark_onPrimary = Color(0xFF213600) val md_theme_dark_primaryContainer = Color(0xFF324F00) // .. // ..
Theme.ktсодержит настройки светлой и тёмной цветовых схем, а также темы приложения.
private val LightColorScheme = lightColorScheme( primary = md_theme_light_primary, onPrimary = md_theme_light_onPrimary, primaryContainer = md_theme_light_primaryContainer, // .. ) private val DarkColorScheme = darkColorScheme( primary = md_theme_dark_primary, onPrimary = md_theme_dark_onPrimary, primaryContainer = md_theme_dark_primaryContainer, // .. ) @Composable fun ReplyTheme( darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit ) { val colorScheme = if (!darkTheme) { LightColorScheme } else { DarkColorScheme } MaterialTheme( colorScheme = colorScheme, content = content ) }
Чтобы поддерживать светлую и тёмную темы, используйте isSystemInDarkTheme(). В зависимости от системных настроек выберите светлую или темную цветовую схему.
Динамические цветовые схемы
Динамические цвета – ключевой элемент Material You. Алгоритм подбирает пользовательские цвета на основе обоев пользователя и применяет их к приложениям и системному интерфейсу. Эта цветовая палитра используется в качестве основы для создания светлой и темной цветовых схем.
Динамические цвета доступны в Android 12 и более поздних версий. Если динамический цвет доступен, вы можете настроить динамическую тему ColorScheme. В противном случае используйте светлую или темную ColorScheme.
ColorScheme предоставляет функции для создания динамической светлой или темной цветовой схемы:
// Dynamic color is available on Android 12+ val dynamicColor = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S val colors = when { dynamicColor && darkTheme -> dynamicDarkColorScheme(LocalContext.current) dynamicColor && !darkTheme -> dynamicLightColorScheme(LocalContext.current) darkTheme -> DarkColorScheme else -> LightColorScheme }
Использование цвета
Вы можете получить доступ к цветам темы Material в приложении с помощью следующих методов:
MaterialTheme.colorScheme
Text( text = "Hello theming", color = MaterialTheme.colorScheme.primary )
Каждая роль цвета может использоваться в разных местах в зависимости от состояния, заметности и акцента компонента.
- Основной цвет используется для главных компонентов, таких как заметные кнопки, активные состояния и оттенок приподнятых поверхностей.
- Второстепенный ключевой цвет используется для менее заметных элементов интерфейса, таких как чипы фильтров, и расширяет возможности для цветового оформления.
- Третий ключевой цвет используется для создания контрастных акцентов, которые могут уравновесить основной и дополнительный цвета или привлечь внимание к определенному элементу.
В дизайне примера приложения Reply используется цвет on-primary-container поверх primary-container, чтобы выделить выбранный элемент.
Card( colors = CardDefaults.cardColors( containerColor = if (isSelected) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceVariant ) ) { Text( text = "Dinner club", style = MaterialTheme.typography.bodyLarge, color = if (isSelected) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurface, ) }
Здесь в панели навигации по ответам можно увидеть, как вторичные и третичные цвета контейнеров используются в контрасте, чтобы создать акцент.
Параметры текста
В Material Design 3 определена шкала шрифтов, включающая стили текста, адаптированные из Material Design 2. Названия и группировка упрощены: теперь есть только такие типы, как "Показ", "Заголовок", "Название", "Текст" и "Ярлык", а также размеры "Большой", "Средний" и "Маленький".
| M3 | Размер шрифта и высота строки по умолчанию |
displayLarge |
Roboto 57/64 |
displayMedium |
Roboto 45/52 |
displaySmall |
Roboto 36/44 |
headlineLarge |
Roboto 32/40 |
headlineMedium |
Roboto 28/36 |
headlineSmall |
Roboto 24/32 |
titleLarge |
New- Roboto Medium 22/28 |
titleMedium |
Roboto Medium 16/24 |
titleSmall |
Roboto Medium 14/20 |
bodyLarge |
Roboto 16/24 |
bodyMedium |
Roboto 14/20 |
bodySmall |
Roboto 12/16 |
labelLarge |
Roboto Medium 14/20 |
labelMedium |
Roboto Medium 12/16 |
labelSmall |
New Roboto Medium, 11/16 |
Как задать типографику
Compose предоставляет класс M3 Typography, а также существующие классы TextStyle и для работы со шрифтами, чтобы моделировать шкалу шрифтов Material 3. Конструктор Typography предлагает значения по умолчанию для каждого стиля, поэтому вы можете опустить любые параметры, которые не хотите настраивать:
val replyTypography = Typography( titleLarge = TextStyle( fontWeight = FontWeight.SemiBold, fontSize = 22.sp, lineHeight = 28.sp, letterSpacing = 0.sp ), titleMedium = TextStyle( fontWeight = FontWeight.SemiBold, fontSize = 16.sp, lineHeight = 24.sp, letterSpacing = 0.15.sp ), // .. ) // ..
Для вашего продукта, скорее всего, не понадобятся все 15 стилей из шкалы типографики Material Design. В этом примере для уменьшенного набора выбрано пять размеров, а остальные опущены.
Вы можете настроить типографику, изменив значения по умолчанию для свойств TextStyle и , связанных со шрифтами, например fontFamily и letterSpacing.
bodyLarge = TextStyle( fontWeight = FontWeight.Normal, fontFamily = FontFamily.SansSerif, fontStyle = FontStyle.Italic, fontSize = 16.sp, lineHeight = 24.sp, letterSpacing = 0.15.sp, baselineShift = BaselineShift.Subscript ),
После того как вы определили Typography, передайте его в M3 MaterialTheme:
MaterialTheme( typography = replyTypography, ) { // M3 app Content }
Как использовать стили текста
Вы можете получить типографику, предоставленную composable-функции M3 MaterialTheme, с помощью MaterialTheme.typography:
Text( text = "Hello M3 theming", style = MaterialTheme.typography.titleLarge ) Text( text = "you are learning typography", style = MaterialTheme.typography.bodyMedium )
Подробнее о том, как использовать типографику, можно узнать в руководстве по Material Design.
Фигуры
Поверхности материалов могут иметь разные формы. Фигуры привлекают внимание, обозначают компоненты, передают состояние и выражают бренд.
Масштаб формы определяет стиль углов контейнера, предлагая диапазон закруглений от квадратного до полностью круглого.
Как задать фигуры
В Compose есть класс M3 Shapes с расширенными параметрами, которые позволяют создавать новые фигуры M3. Масштаб M3 больше похож на масштаб шрифта, поэтому позволяет использовать в интерфейсе более разнообразные формы.
Фигуры бывают разных размеров:
- Очень мелкий
- Мелкий
- Средний
- Крупный
- Очень крупный
По умолчанию у каждой фигуры есть значение по умолчанию, но вы можете его изменить:
val replyShapes = Shapes( extraSmall = RoundedCornerShape(4.dp), small = RoundedCornerShape(8.dp), medium = RoundedCornerShape(12.dp), large = RoundedCornerShape(16.dp), extraLarge = RoundedCornerShape(24.dp) )
После того как вы определили Shapes, его можно передать в MaterialTheme M3:
MaterialTheme( shapes = replyShapes, ) { // M3 app Content }
Как использовать фигуры
Вы можете настроить масштаб формы для всех компонентов в MaterialTheme или для каждого компонента отдельно.
Применить среднюю и большую фигуры со значениями по умолчанию:
Card(shape = MaterialTheme.shapes.medium) { /* card content */ } FloatingActionButton( shape = MaterialTheme.shapes.large, onClick = { } ) { /* fab content */ }
В Compose также есть два других символа: RectangleShape и CircleShape. Прямоугольник без радиуса скругления и круг с полностью скругленными краями:
Card(shape = RectangleShape) { /* card content */ } Card(shape = CircleShape) { /* card content */ }
Ниже приведены примеры компонентов с примененными к ним значениями формы по умолчанию:
Подробнее о применении формы в Material Design…
Выделение
В M3 акцент создается с помощью сочетаний цветов и их оттенков. В M3 есть два способа сделать акцент на элементах интерфейса:
- Используйте цвета surface, surface-variant и background вместе с цветами on-surface и on-surface-variants из расширенной цветовой системы M3. Например, surface можно использовать с on-surface-variant, а surface-variant – с on-surface, чтобы задать разные уровни акцента.
- Использование разных вариантов начертания шрифта. Выше мы уже говорили о том, что для разных шрифтов можно задавать разные веса.
bodyLarge = TextStyle( fontWeight = FontWeight.Bold ), bodyMedium = TextStyle( fontWeight = FontWeight.Normal )
Высота над уровнем моря
В Material 3 высота обозначается в основном с помощью наложений тональных цветов. Это новый способ различать контейнеры и поверхности. В дополнение к теням используется тональное выделение: чем выше тональность, тем заметнее тон.
В Material 3 на тёмных темах наложения высоты заменены наложения тональных цветов. Цвет наложения берется из основного цвета.
Компонент M3 Surface (composable-функция, лежащая в основе большинства компонентов M3) поддерживает как тональную, так и теневую высоту:
Surface( modifier = Modifier, tonalElevation = /*... shadowElevation = /*... ) { Column(content = content) }
Компоненты материалов
В Material Design есть множество компонентов (например, кнопки, чипы, карточки, панель навигации), которые уже соответствуют принципам Material Theming и помогают создавать красивые приложения в стиле Material Design. Вы можете сразу начать использовать компоненты со свойствами по умолчанию.
Button(onClick = { /*..*/ }) { Text(text = "My Button") }
В M3 предусмотрено множество версий одних и тех же компонентов, которые можно использовать в разных ролях в зависимости от того, на чем нужно сделать акцент.
- Расширенная плавающая кнопка действия для наиболее важного действия:
ExtendedFloatingActionButton( onClick = { /*..*/ }, modifier = Modifier ) { Icon( imageVector = Icons.Default.Edit, contentDescription = stringResource(id = R.string.edit), ) Text( text = stringResource(id = R.string.add_entry), ) }
- Заполненная кнопка для действий, на которых нужно сделать акцент:
Button(onClick = { /*..*/ }) { Text(text = stringResource(id = R.string.view_entry)) }
- Текстовая кнопка для действия, которое не нужно выделять:
TextButton(onClick = { /*..*/ }) { Text(text = stringResource(id = R.string.replated_articles)) }
Подробнее о кнопках и других компонентах Material… Material 3 предлагает широкий выбор наборов компонентов, таких как кнопки, панели приложений и навигационные компоненты, которые специально разработаны для разных вариантов использования и размеров экрана.
Компоненты навигации
Кроме того, в Material есть несколько компонентов навигации, которые помогают реализовать навигацию в зависимости от размера экрана и состояния.
NavigationBar используется для компактных устройств, когда нужно настроить таргетинг на пять или менее целевых страниц:
NavigationBar(modifier = Modifier.fillMaxWidth()) { Destinations.entries.forEach { replyDestination -> NavigationBarItem( selected = selectedDestination == replyDestination, onClick = { }, icon = { } ) } }
NavigationRail – для небольших и средних планшетов или телефонов в альбомной ориентации. Это повышает удобство использования устройств.
NavigationRail( modifier = Modifier.fillMaxHeight(), ) { Destinations.entries.forEach { replyDestination -> NavigationRailItem( selected = selectedDestination == replyDestination, onClick = { }, icon = { } ) } }
BottomNavigationBar (слева) и NavigationRail (справа)Ответы должны быть оформлены в соответствии с темой по умолчанию, чтобы пользователям было удобно читать их на устройствах любого размера.
NavigationDrawer – для планшетов среднего и большого размера, на которых достаточно места для показа подробной информации. Вы можете использовать как PermanentNavigationDrawer, так и ModalNavigationDrawer вместе с NavigationRail.
PermanentNavigationDrawer(modifier = Modifier.fillMaxHeight(), drawerContent = { Destinations.entries.forEach { replyDestination -> NavigationRailItem( selected = selectedDestination == replyDestination, onClick = { }, icon = { }, label = { } ) } }) { }
Варианты навигации повышают удобство использования, эргономичность и доступность. Подробнее о компонентах навигации Material Design можно узнать в практической работе по адаптивному макету Compose.
Как настроить тему компонента
M3 поддерживает персонализацию и гибкость. Для всех компонентов заданы цвета по умолчанию, но при необходимости их можно изменить с помощью API.
Большинство компонентов, например карточки и кнопки, предоставляют объект по умолчанию, который позволяет изменять цвет и высоту:
val customCardColors = CardDefaults.cardColors( contentColor = MaterialTheme.colorScheme.primary, containerColor = MaterialTheme.colorScheme.primaryContainer, disabledContentColor = MaterialTheme.colorScheme.surface, disabledContainerColor = MaterialTheme.colorScheme.onSurface, ) val customCardElevation = CardDefaults.cardElevation( defaultElevation = 8.dp, pressedElevation = 2.dp, focusedElevation = 4.dp ) Card( colors = customCardColors, elevation = customCardElevation ) { // m3 card content }
Подробнее о настройке Material 3…
Интерфейс системы
Некоторые аспекты Material You связаны с новым визуальным стилем и системным интерфейсом Android 12 и более поздних версий. Изменения коснулись двух основных областей: эффекта волны и эффекта достижения конца прокрутки. Для внедрения этих изменений никаких дополнительных действий не требуется.
Рябь
Теперь при нажатии на экран появляется легкая рябь. Compose Material Ripple использует RippleDrawable платформы на устройствах Android, поэтому эффект мерцания доступен на Android 12 и более поздних версиях для всех компонентов Material.
Эффект достижения конца прокрутки
Теперь при достижении конца прокрутки используется эффект растяжения на краю прокручиваемых контейнеров.
По умолчанию растягивание при достижении конца прокрутки включено в composable-функциях контейнеров с прокруткой, например LazyColumn, LazyRow и LazyVerticalGrid, в Compose Foundation версии 1.1.0 и выше независимо от уровня API.
Специальные возможности
Стандарты специальных возможностей, встроенные в компоненты Material, предназначены для создания инклюзивного дизайна продуктов. Понимание того, насколько доступен ваш продукт, может повысить удобство его использования для всех пользователей, в том числе с нарушениями зрения, слуха, когнитивных функций или моторики, а также с временными ограничениями возможностей (например, сломанной рукой).
Специальные возможности: цвета
Динамические цвета соответствуют стандартам доступности в отношении контрастности. Система тональных палитр необходима для того, чтобы цветовая схема была доступна по умолчанию.
Система цветов Material содержит стандартные значения тонов и измерения, которые можно использовать для достижения доступных коэффициентов контрастности.
Все компоненты Material и динамическое оформление уже используют указанные выше роли цвета из набора тональных палитр, выбранных с учетом требований к доступности. Однако при настройке компонентов необходимо использовать подходящие роли цветов и избегать несоответствий.
Используйте on-primary поверх primary, on-primary-container поверх primary-container и так далее для других акцентных и нейтральных цветов, чтобы обеспечить доступный контраст для пользователя.
Использование третичного контейнера поверх основного приводит к тому, что кнопка имеет низкий контраст:
// ✅ Button with sufficient contrast ratio Button( onClick = { }, colors = ButtonDefaults.buttonColors( containerColor = MaterialTheme.colorScheme.primary, contentColor = MaterialTheme.colorScheme.onPrimary ) ) { } // ❌ Button with poor contrast ratio Button( onClick = { }, colors = ButtonDefaults.buttonColors( containerColor = MaterialTheme.colorScheme.tertiaryContainer, contentColor = MaterialTheme.colorScheme.primaryContainer ) ) { }
Специальные возможности типографики
Шкала типа M3 обновляет статическую шкалу типов и значения, чтобы предложить упрощенную, но динамическую структуру категорий размеров, которые масштабируются на разных устройствах.
Например, в M3 размер "Маленький экран" может иметь разные значения в зависимости от контекста устройства, например телефона или планшета.
Большие экраны
В Material Design есть рекомендации по адаптивным макетам и складным устройствам, которые помогут сделать ваши приложения доступными и удобными для пользователей больших устройств.
В Material Design есть разные виды навигации, которые помогут вам сделать интерфейс приложения более удобным для пользователей больших экранов.
Ознакомьтесь с рекомендациями по обеспечению качества приложений для устройств с большим экраном и примером приложения "Ответ" с адаптивным и доступным дизайном.
Подробнее…
Чтобы узнать больше о тематическом оформлении Material Design в Compose, ознакомьтесь со следующими ресурсами:
Примеры приложений
Документы
Документация по API и исходный код
Видео
Рекомендуем
- Примечание. Текст ссылки показывается, когда JavaScript отключен.
- Как перейти с Material 2 на Material 3 в Compose
- Material Design 2 в Compose
- Специальные системы проектирования в Compose