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

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

Как реализовать тёмную тему в 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/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:windowTranslucentNavigation">true</item>
        <item name="android:navigationBarColor">@android:color/transparent</item>
</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.

Ресурсы для тёмной темы

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

Перевод статьи «How to Implement Day/Night Mode in Your Android App»

ПОХОЖИЕ ПУБЛИКАЦИИ

2123
12/09/2019

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

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

Сайт использует cookie-файлы для того, чтобы вам было удобнее им пользоваться. Для продолжения работы с сайтом, вам необходимо принять использование cookie-файлов.

Я ознакомлен(а)