Прямые ссылки на публичные уроки для быстрого старта и стабильной индексации lesson-страниц.
В этом уроке рассмотрим работу со стилями и темами в Jetpack Compose. Повторяющиеся модификаторы оформления — например, для текстов — принято выносить в стили. Кроме того, стандартом считается поддержка темной темы, если она включена на устройстве.
Начнем с реализации темной темы. При её активации на эмуляторе интерфейс операционной системы меняется, однако приложение остается в прежней цветовой схеме — потому что мы явно прописали практически все значения, как минимум для текстов.
Темы настраиваются в файле ui.theme.Theme.kt. Здесь прописаны две переменные с цветами для светлой и темной тем, а также основная функция темы приложения, которая оборачивает всё содержимое.
Параметры функции:
darkTheme — определяет, включена ли темная тема на устройстве (значение берется из системы автоматически).dynamicColor — управляет динамическим цветовым оформлением. Позволяет использовать цвета на основе обоев или темы устройства (актуально для Android 12+).content — ожидает composable функцию, то есть содержимое экрана.Размещая контент внутри функции темы, мы получаем доступ к её цветам. Внутри реализована простая логика: colorScheme выбирается через when — динамический цвет (при подходящей версии Android), темная или светлая палитра. Динамический цвет я закомментирую, чтобы избежать непредсказуемого поведения. Только темная и светлая палитры.
В результате вызывается MaterialTheme, которая объединяет цветовую схему, объект типографики и контент экрана.
В файле есть комментарий с примерами цветов для переопределения. Цветовая схема основана на Material Design:
primary — основной цвет приложения: кнопки, выделенные блоки.secondary — второстепенный цвет: вторичные кнопки, активные элементы в секциях.tertiary — третичный цвет: иконки, линии выделения, маркеры.surface — карточки, модальные окна, попапы.background — фон приложения.on — цвет текста или иконок поверх соответствующего фона.Добавим недостающие цвета в файл палитры. Для светлой темы: цвет фона (не чисто белый), почти черный для заголовков и серый для подзаголовков. Для темной темы инвертируем значения, добавив постфикс Dark к именам.
В файле темы переопределяем background и surface для обеих тем. Главное — не забыть обернуть всё содержимое setContent в функцию темы приложения. После этого можно переключить темную тему и собрать проект.
Переопределяем onBackground для обеих тем — это основной цвет текста в приложении. Для проверки временно поставим яркий цвет 0xFFFF00B4): Material автоматически применит onBackground ко всем текстам на фоне, после чего можно заменить на нужные цвета.
Дополнительно настраиваем цвет кнопок. Material использует primary как цвет поверхности кнопок: для светлой темы — близкий к черному, для темной — наоборот.
Если нужно явно применить конкретный цвет к отдельному элементу (например, к тексту на кнопке), обращаемся к MaterialTheme: color = MaterialTheme.colorScheme.onBackground .
Цвет будет автоматически меняться в зависимости от темы устройства.
Если ни один из стандартных цветов схемы не подходит, создаём собственное свойство-расширение класса ColorScheme. Внутри определяем геттер, который возвращает нужный цвет в зависимости от темы:
val ColorScheme.subtitle: Color @Composable get() = if (isSystemInDarkTheme()) subtitleGrayColorDark else subtitleGrayColor
Используем это свойство при установке цвета текста:
style = MaterialTheme.typography.headlineLarge style = MaterialTheme.typography.headlineMedium
Для корректного отображения в превью создаём отдельные функции для светлой и темной тем. В параметр darkTheme функции темы приложения передаём true или false принудительно:
@Composable @Preview(showBackground = true) private fun MainNavButtonsPreviewLight() { ComposePreviewTheme( darkTheme = false ) { MainNavButtons() } } @Composable @Preview(showBackground = true) private fun MainNavButtonsPreviewDark() { ComposePreviewTheme( darkTheme = true ) { MainNavButtons() } }
Повторяющиеся параметры оформления текста можно объединить в стили. Настройка типографики происходит в файле Type.kt через класс Typography.
Typography содержит набор текстовых стилей по Material Design 3: шрифт, размер, вес, межстрочное расстояние, межбуквенный интервал. Полный список стилей можно посмотреть, провалившись в декларацию класса. Такой подход обеспечивает единообразие текста по всему приложению и соответствие рекомендациям Material Design.
Переопределяем нужные стили:
headlineLarge (шрифт и размер).headlineMedium.Применяем стили через параметр style:
style = MaterialTheme.typography.headlineLarge style = MaterialTheme.typography.headlineMedium
На превью без явного указания темы размер может отличаться — подтягивается значение по умолчанию из Material. Для демонстрационного проекта это не критично.
В следующем уроке рассмотрим важные концепции состояния и рекомпозиции.