Как поменять тему в андроид студио
Перейти к содержимому

Как поменять тему в андроид студио

  • автор:

Как поменять тему в андроид студио

Кроме применение отдельных стилей к отдельным элементам, мы можем задавать стили для всего приложения или activity в виде тем. Тема предтавляет коллекцию атрибутов, которые применяются в целом ко всему приложению, классу activity или иерархии виджетов.

Мы можем сами создать тему. Однако Android уже предоставляет несколько предустановленных тем для стилизации приложения, например, Theme.AppCompat.Light.DarkActionBar и ряд других.

По умолчанию приложение уже применяет темы. Так, откроем файл AndroidManifest.xml . В нем мы можем увидеть следующее определение элемента application, представляющего приложение:

Задание темы происходит с помощью атрибута android:theme . В данном случае используется ресурс, который называется в моем случае Theme.ViewApp . По умолчанию файлы тем определены в папке res/values . В частности, здесь можно найти условный каталог themes , в котором по умолчанию есть два элемента: themes.xml :

Темы и стили в Android Studio и Java

Один файл представляет светлую тему, а другой — темную. Например, откроем файл themes.xml со светлой темой:

    @color/purple_500 @color/purple_700 @color/white @color/teal_200 @color/teal_700 @color/black ?attr/colorPrimaryVariant  

Здесь мы можем увидеть, что тема определяется как и стиль с помощью элемента style .. Атрибут parent указывает на родительскую тему, от которой текущая тема берет все стилевые характеристики. То есть тема «Theme.ViewApp» использует другую тему — «Theme.MaterialComponents.DayNight.DarkActionBar». И кроме того, определяет ряд своих собственных стилей.

Также можно заметить, что здесь определяются не только характеристики для атрибутов, но и семантические имена, например, colorPrimary , которому сопоставлен ресурс «@color/purple_500».

При необходимости мы можем изменить эти характеристики или дополнить тему новыми стилевыми характеристиками. Например, изменим цвет свойства colorPrimary , которое применяется в том числе в качестве фонового цвета заголовка и кнопки:

#1565C0

И соответственно изменится цвет по умолчанию для фона заголовка и кнопки:

Theme Editor in Android Studio

Создание собственной темы

Вместо использования встроенных тем мы можем создать свою. Для этого добавим в папку res/values новый файл mythemes.xml и определим в нем следующее содержимое:

     

Определение своей темы

Итак, мы создали стиль «MyTheme», который унаследован от стиля Theme.AppCompat.Light . В этом стиле мы переопределили два свойства: высоту шрифта (textSize) — 28sp, а также цвет текста (textColor) — #FF018786 .

Теперь определим этот стиль в качестве темы приложения в файле AndroidManifest.xml :

Пусть у нас будет следующая разметка в activity_main.xml

Как видно, для элементов TextView не устанавливается атрибут textSize и textColor , однако поскольку они определены в теме, которая применяется глобально к нашему приложению, то элементы TextView будут подхватывать эти стилевые характеристики:

Создание новой темы для Android

Применение темы к activity

Выше темы применялись глобально ко всему приложению. Но также можно применить их к отдельному классу Activity. Для этого надо подкоррективать файл манифеста AndroidManifest. Например:

Атрибут android:theme элемента указывает на применяемую к MainActivity тему. То есть глобально к приложению применяется тема «Theme.ViewApp», а к MainActivity — «MyTheme».

Применение темы к иерархии виджетов

Также можно применить тему к иерархии виджетов, установив атрибут android:theme у элемента, к которому (включая его вложенные элементы) мы хотим применить тему. Например, примение темы к ConstraintLayout и ее элементам:

DayNight: настраиваем автоматическую смену темы в android в зависимости от времени суток

Мы уже писали, что вышла новая библиотека поддержки Android Support Library 23.2. Новая либа добавляет сразу несколько интересных вещей: это и поддержка векторных изображений в android ниже 5.0, и новые элементы материального дизайна, такие как Bottom Sheets.

Одна из фишек – новая тема DayNight с поддержкой автоматического переключения между светлой и темной темой оформления в зависимости от времени суток. Ее то мы сегодня и потестируем.

Об этом смотрите видео, а под видео – подробнее от разработчиков том, как гибко можно настроить работу и ресурсы для темы DayNight.

Theme.AppCompat.DayNight – это переключение между Theme.AppCompat (темной) и Theme.AppCompat.Light (светлой) на основе времени суток. Это имеет много преимуществ для пользователей, особенно если у вас content app . Эта функция работает на API v14 и выше, на младших версиях будет по умолчанию светлая тема.

Как использовать Theme.AppCompat.DayNight ?

Просто унаследуйте вашу тему от одного из вариантов DayNight в файле res/values/styles.xml:

Затем необходимо включить функцию в вашем приложении. Сделайте это путем вызова статического метода AppCompatDelegate.setDefaultNightMode(), который принимает одно из четырех значений:

  • MODE_NIGHT_NO. Всегда используется дневная тема (светлая).
  • MODE_NIGHT_YES. Всегда используется ночная тема (темная).
  • MODE_NIGHT_AUTO. Автоматическое изменение между светлой/темной, в зависимости от времени суток.
  • MODE_NIGHT_FOLLOW_SYSTEM (по умолчанию). Это системный параметр, который является по существу MODE_NIGHT_NO на момент написания (подробнее об этом ниже).

Вызов метода static, поэтому его можно вызвать в любое время. Устанавливаемое значение не сохраняется, поэтому вам нужно установить его каждый раз, когда ваше приложение стартует. Рекомендуется устанавливать его в статический блок в классе вашего приложения (если у вас он один), или вашей Activity, так:

static

Метод setLocalNightMode()

Можно переопределить значение по умолчанию в каждом компоненте путем вызова его AppCompatDelegate setLocalNightMode(). Это удобно, когда вы знаете, что только некоторые компоненты должны использовать функцию DayNight, или для тестирования, чтобы не сидеть и ждать ночи для проверки макета.

Обратите внимание, что этот вызов не заботится о восстановлении, если изменить режим ночь после любого вызова inflate(), он не будет иметь никакого эффекта. В этом случае можно использовать вызов recreate():

public class MyActivity extends AppCompatActivity < public void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); if (savedInstanceState == null) < // Set the local night mode to some value getDelegate().setLocalNightMode( AppCompatDelegate.MODE_NIGHT_. ); // Now recreate for it to take effect recreate(); >> >
Как проверить, какой режим может использовать мое приложение?

Просто проверьте конфигурацию ресурсов:

int currentNightMode = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; switch (currentNightMode) < case Configuration.UI_MODE_NIGHT_NO: // Night mode is not active, we're in day time case Configuration.UI_MODE_NIGHT_YES: // Night mode is active, we're at night! case Configuration.UI_MODE_NIGHT_UNDEFINED: // We don't know what mode we're in, assume notnight >
Если приложение выглядит странно

Например, текст нечитабельный или иконки неправильного цвета.

Поскольку эта функция изменяет тему вашего приложения, вам нужно убедиться, что ваши макеты/стили/графика корректно отображались в светлых и темных условиях.

Возьмите за правило для этих вещей всегда использовать атрибуты темы, по возможности. Вот наиболее важные:

  • ?android:attr/textColorPrimary – Цвет текста общего назначения. Будет черным для светлой темы, и белым для темной темы.
  • ?attr/colorControlNormal – Цвет значка общего назначения.
WebView

Существует один большой нюанс этой функции: WebViews. Поскольку они не могут использовать атрибуты темы, и вы редко имеете контроль над любым веб-контентом, существует высокая вероятность того, что ваш WebView будет слишком контрастным против динамического оформления приложения. Поэтому проверьте ваше приложение в обоих режимах, чтобы убедиться что оформление не будет раздражать пользователя.

Местоположение

Чтобы иметь возможность рассчитать корректное переключение между днем или ночью, нам нужно знать ваше местоположение. Если ваше приложение уже имеет разрешения для определения местоположения, AppCompat будет попытаться захватить последнее известное местоположение от LocationManager и использовать их для вычисления времени восхода и захода солнца. Однако он не будет просить разрешения от вашего имени.
Если вы не установили эти разрешения (или просто нет последнего известного местоположения), в настоящее время используются некоторые фиксированные значения. Например это 6 утра (начало дня) и 10 вечера (начало ночи), но это может измениться в будущем, по словам разработчиков.
Если вы ориентируетесь на Android SDK версии 23, вы будете использовать разрешения времени выполнения. Можно реализовать в вашем приложении настройку, позволяя пользователю выбрать включение функциональности DayNight. Это хороший способ, чтобы запрашивать разрешения определения местоположения, если требуется высокая точность определения времени восхода/заката.

Почему просто не сделать AUTO по умолчанию?

Существует несколько причин, которые станут понятны после просмотра примерного сценария для использования этого:

  1. Изменить тему продления от Theme.AppCompat.DayNight.
  2. Добавить установку в вашем приложении, предоставив пользователю выбор. На этом этапе сохранить настройки (вероятно, в SharedPreference). Вызов setDefaultNightMode () с выбранным значением.

Тогда в следующий раз, когда ваше приложение запускается, прочитать сохраненное значение и вызвать setDefaultNightMode () снова с выбранным значением.

Таким образом, основная причина заключается в том , не желательно, чтобы ваш пользователь обновил приложение, и вдруг обнаружил , что оно меняет цвет случайным образом (для него) на основе времени суток. Кроме того, по умолчанию MODE_NIGHT_FOLLOW_SYSTEM, поэтому если разработчики добавят user-visible setting на платформу в будущем, AppCompat будет автоматически использовать его.

Можно ли использовать свои собственные ресурсы для темы день / ночь?

Да, можно. AppCompat в простых терминах просто позволяет использовать отдельные ресурсы ночного режима в любое время. Они на самом деле были доступны в платформе, начиная с API 8, но использовались только в очень конкретном сценарии: в режиме автомобиля и стыковки.

Так что под капотом Theme.AppCompat.DayNight просто реализован в таком виде:

res/values/themes.xml

res/values-night/themes.xml

Это означает, что вы можете также добавить ваши ресурсы для дневного и ночного времени. Просто используйте –night квалификатор для вашей папки ресурсов: drawable-night, values-night, и т.д.

Вам також може сподобатися

Пример использования Android ConstraintLayout в сложном UI

Дизайн android приложений 0 8 079

Перевод статьи на Медиуме о построении пользовательского интерфейса с помощью компонента разметки ConstraintLayout. Создайте

Работа с ConstraintLayout в Android Studio

Дизайн android приложений 2 1 892

[:ru]Сегодня в очередном выпуске Дизайна андроид приложений обзор интересной библиотеки от команды DevLight. Кто

Работа с ConstraintLayout в Android Studio

Дизайн android приложений 1 1 833

В этом учебнике мы создадим простое Android приложение для отображения списка данных с использованием ViewStub

Работа с ConstraintLayout в Android Studio

Дизайн android приложений 0 5 958
В этом уроке вы узнаете, как создавать интерактивные значки для пунктов меню, отображаемых в тулбаре

Android Учебник: создание RecyclerView, CardView и меню опций для элемента RecyclerView

Дизайн android приложений 0 10 956
Android Учебник: создание RecyclerView, CardView и меню опций для элемента RecyclerView В этом уроке

Как добавить BottomNavigationView в ваше android приложение

Дизайн android приложений 0 24 910

Рассмотрим новый компонент библиотеки поддержки материального дизайна BottomNavigationView. Это нижняя панель навигации, позволяющая переключаться между

Коментарі: 2

У меня в приложении по собственному стилю цвет текста (заголовка) в action bar был белый, но после установки на DayNight стал чёрным, и никакие стили и темы никак не влияют, чтобы обратно сделать белым, как это решить?

Додати коментар Скасувати відповідь

Щоб відправити коментар вам необхідно авторизуватись.

Как реализовать тёмную тему в Android-приложении?

С тех пор, как в Android Pie (9.0) появилась тёмная тема, многие популярные приложения с радостью начали использовать эту функцию. И мы тоже. Учитывая, что нам нравится пробовать новые вещи, мы решили попробовать и внедрить эту функцию в одно из наших приложений.

Я максимально просто опишу процесс реализации тёмной темы приложения с использованием библиотеки AppCompat из AndroidX.

Прежде чем мы начнём, вот вам совет: если вы работаете над какими-либо новыми проектами, то настоятельно рекомендуется использовать библиотеки из AndroidX. Кроме того, вам следует рассмотреть возможность переноса существующих проектов на AndroidX.

Теперь давайте начнём

Сначала импортируйте последнюю версию AppCompat из AndroidX:

implementation 'androidx.appcompat:appcompat:1.1.0-alpha05'

В этой версии AppCompat будут все новые обновления и исправленные ошибки, связанные с тёмной темой.

Затем измените тему своего приложения на Theme.AppCompat.DayNight :

style name="AppTheme" parent="Theme.AppCompat.DayNight.DarkActionBar"> item name="colorPrimary">@color/colorPrimaryitem> item name="colorPrimaryDark">@color/colorPrimaryDarkitem> item name="colorAccent">@color/colorAccentitem> item name="android:windowTranslucentNavigation">trueitem> item name="android:navigationBarColor">@android:color/transparentitem> style>

Переходим к коду

Измените текущую тему во время запуска приложения (рекомендуется делать это в классе Application приложения). Начиная с версии 1.1.0-aplha05 этот метод будет применять эти изменения к любой запущенной activity. Изменения также будут сохраняться при всех изменениях конфигурации, поэтому не нужно вызывать метод recreate() .

override fun onCreate() < super.onCreate() AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.getDefaultNightMode()) >

Вот четыре режима, которые мы используем в нашем приложении для выбора темы:

  • MODE_NIGHT_NO — устанавливает светлую тему.
  • MODE_NIGHT_YES — устанавливает тёмную тему.
  • MODE_NIGHT_AUTO_BATTERY — переключается на тёмную тему, если на устройстве включена функция экономии заряда батареи. Этот режим доступен с версии 1.1.0-alpha03 .
  • MODE_NIGHT_FOLLOW_SYSTEM — использует системную тему.
  • MODE_NIGHT_AUTO_TIME и MODE_NIGHT_AUTO — устанавливает тему в зависимости от времени устройства. Этот режим устарел с версии 1.1.0-alpha03 , поэтому мы не используем его в нашем приложении.

Внутри приложения есть RadioGroup для переключения между различными темами:

private fun initThemeListener()< themeGroup.setOnCheckedChangeListener < _, checkedId -> when (checkedId) < R.id.themeLight -> setTheme(AppCompatDelegate.MODE_NIGHT_NO, THEME_LIGHT) R.id.themeDark -> setTheme(AppCompatDelegate.MODE_NIGHT_YES, THEME_DARK) R.id.themeBattery -> setTheme(AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY, THEME_BATTERY) R.id.themeSystem -> setTheme(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM, THEME_SYSTEM) > > > private fun setTheme(themeMode: Int, prefsMode: Int) < AppCompatDelegate.setDefaultNightMode(themeMode) saveTheme(prefsMode) >

Вот как это выглядит на устройстве:

Не забывайте, что функциональность тёмной темы поддерживается только с версии Android Pie (9.0), поэтому вам нужно предусмотреть поведение для предыдущих версий Android:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)< themeSystem.visibility = View.VISIBLE > else < themeSystem.visibility = View.GONE >

Проверка текущей темы системы

Фрагмент из нашего приложения:

when (resources.configuration.uiMode.and(Configuration.UI_MODE_NIGHT_MASK)) < Configuration.UI_MODE_NIGHT_NO -> themeLight.isChecked = true Configuration.UI_MODE_NIGHT_YES -> themeDark.isChecked = true Configuration.UI_MODE_NIGHT_UNDEFINED -> themeLight.isChecked = true >

Обратите внимание, что конфигурация возвращается только при наличии ночной или дневной темы (или если вообще ничего не определено), но мы не знаем, установлена ли она системой, батареей или вручную. Поэтому мы используем shared preferences, чтобы сохранить выбранную тему и установить соответствующий флажок. Вот полный код:

when (getSavedTheme()) < THEME_LIGHT -> themeLight.isChecked = true THEME_DARK -> themeDark.isChecked = true THEME_SYSTEM -> themeSystem.isChecked = true THEME_BATTERY -> themeBattery.isChecked = true THEME_UNDEFINED -> < when (resources.configuration.uiMode.and(Configuration.UI_MODE_NIGHT_MASK)) < Configuration.UI_MODE_NIGHT_NO -> themeLight.isChecked = true Configuration.UI_MODE_NIGHT_YES -> themeDark.isChecked = true Configuration.UI_MODE_NIGHT_UNDEFINED -> themeLight.isChecked = true > > >

Когда приложение запускается в первый раз, в shared preferences будет неопределённое состояние. В этом случае мы проверим, есть ли у нас тема из конфигурации. Если нет, мы будем использовать светлую тему по умолчанию.

Ещё немного настроек

Если вы хотите использовать пользовательские цвета для тёмной/светлой темы (например, тёмно-синий для тёмной и светло-синий для светлой), то создайте папку values-night и переопределите файл цветов. Также можно переопределить styles.xml и использовать пользовательские атрибуты. Таким образом, приложение всегда будет использовать цвета из values-night , когда включена тёмная тема, и наоборот. Вы также можете подготовить альтернативные ресурсы для тёмной темы. Например, в drawable-night .

Весь исходный код ищите здесь.

Как сделать смену темы в android приложении?

Допустим я написал приложение, дал свои цвета кнопкам, тексту и др компонентам. Потом делаю PreferencesActivity и туда добавляю «изменить тему» и выбор — light(default), dark, deepdark, green и т.д в этом духе. То, если юзер выбирает тему, то как сделать это? Применить к каждому компоненту свой цвет? Если брать тему, то это же набор уже готовых вещей, а у меня цвета свои кастомные(эта кнопка такого цвета, эта кнопка другого, а при смене темы они должны обе поменять свой цвета на другие). Неужели для каждого компонента прописывать свой цвет потом исходя из настроек? Надеюсь вы меня поняли)

  • Вопрос задан более трёх лет назад
  • 3234 просмотра

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *