Android DayNight Theme для ночного режима в приложении
В этом уроке мы обсудим тему Android DayNight и используем ее в нашем приложении. Если у вас есть приложение с материалами для чтения, то наличие ночного режима полезно для глаз.
Тема дня и ночи для Android
Android выпустила новую тему: Theme.AppCompat.DayNight
с библиотекой поддержки 23.2.0
. Благодаря этой теме мы теперь можем переключаться между светлым и темным режимами нашего приложения. Мы можем сделать это вручную или позволить Android автоматически определять время суток с вашего телефона. Эта тема повышает читабельность и удобство использования вашего приложения в ночное время, заменяя яркий белый фон более темным. Многие приложения для чтения уже развернули эту тему в своих приложениях. Давайте начнем с нашей реализации, создав новый проект Android Studio с пустой активностью.
Добавляем тему в наш styles.xml
Заменим текущую тему в нашем приложении на DayNight.
<style name="AppTheme" parent="Theme.AppCompat.DayNight">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
Чтобы установить тему DayNight в нашем приложении, мы используем метод: AppCompatDelegate.setDefaultNightMode()
Ниже приведены аргументы, разрешенные в приведенном выше методе.
MODE_NIGHT_YES
– включает ночной режим вручную.MODE_NIGHT_NO
– вручную отключает ночной режим.MODE_NIGHT_FOLLOW_SYSTEM
— использует системные настройки для определения времени суток и соответствующим образом переключает ночной режим. Это аргумент по умолчанию.MODE_NIGHT_AUTO
— пытается автоматически определить время с помощью API определения местоположения устройства. Если разрешение времени выполнения для служб определения местоположения не предоставлено, используется системное время.
Добавьте следующий код в метод onCreate()
.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); //For night mode theme
//AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); //For day mode theme
setContentView(R.layout.activity_main);
}
Тема всегда должна быть установлена до вызова метода setContentView
.
Что такое AppCompatDelegate?
<style name="AppTheme" parent="Theme.AppCompat.DayNight">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:textColorPrimary">@android:color/white</item>
<item name="android:textColorSecondary">@android:color/white</item>
</style>
Чтобы получить текущий тип ночного режима, мы используем метод AppCompatDelegate.getDefaultNightMode()
, который возвращает целое число для каждого из рассмотренных ранее типов соответственно. Имея базовую идею, давайте сделаем приложение, которое будет:
- Настройка ресурсов, стилей в дневном/ночном режимах.
- Переключить тему DayNight из пользовательского интерфейса
- Посмотрите, как различные виджеты пользовательского интерфейса выглядят в ночном режиме.
Структура проекта ночного режима Android
Пример кода темы Android DayNight
Код для файла класса activity_main.xml приведен ниже.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_margin="@android:dimen/app_icon_size"
android:text="Welcome to this tutorial."
android:textColor="@color/daynight_textColor"
android:textSize="18sp" />
<ImageView
android:id="@+id/imageView"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_centerInParent="true"
android:src="@drawable/placeholder" />
<TextView
android:id="@+id/txtNightMode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/switchCompat"
android:layout_centerHorizontal="true"
android:paddingRight="8dp"
android:text="Night Mode"
android:textColor="@color/daynight_textColor" />
<android.support.v7.widget.SwitchCompat
android:id="@+id/switchCompat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="@android:dimen/app_icon_size"
android:layout_toRightOf="@+id/txtNightMode"
android:checked="false"
android:textAppearance="?android:attr/textAppearanceMedium" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/imageView"
android:layout_alignLeft="@+id/txtNightMode"
android:layout_alignStart="@+id/txtNightMode"
android:text="CLICK ME"
android:textColor="@color/daynight_textColor" />
</RelativeLayout>
- Мы установили пользовательский цвет текста и возможность его рисования в ImageView.
- Чтобы установить разные цвета и рисунки для дневной и ночной тем, нам нужно создать отдельные папки для ресурсов.
- Ресурсы дневной темы находятся в каталоге по умолчанию.
- Ресурсы ночной темы находятся в папках, имена которых заканчиваются с -night.
- Поэтому мы создали папки
values-night
иdrawable-night
в нашем проекте. - Доступное имя файла, цвета и имена стилей должны быть одинаковыми в обоих каталогах для ресурсов, которые вы хотите переключать в теме DayNight.
- Если вышеуказанные вещи определены только в одном из каталогов, то же самое будет использоваться в дневной и ночной темах.
Ниже приведен код стилей.xml в папках values и values-night.
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.DayNight">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:textColorPrimary">@android:color/white</item>
</style>
<style name="MyDialog" parent="Theme.AppCompat.Light.Dialog.Alert"/>
<style name="MySwitch">
<item name="colorControlActivated">@color/switchColor</item>
</style>
</resources>
<resources>
<!-- Base application theme. values-night.xml -->
<style name="AppTheme" parent="Theme.AppCompat.DayNight">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/orange</item>
<item name="colorPrimaryDark">@color/orangeDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:textColorPrimary">@android:color/white</item>
</style>
<style name="MyDialog" parent="Theme.AppCompat.DayNight.Dialog.Alert"/>
<style name="MySwitch">
<item name="colorControlActivated">@color/switchColor</item>
</style>
</resources>
package com.journaldev.daynightmode;
import android.content.Intent;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.app.AppCompatDelegate;
import android.support.v7.widget.SwitchCompat;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (InitApplication.getInstance().isNightModeEnabled()) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
} else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
}
setContentView(R.layout.activity_main);
SwitchCompat switchCompat = findViewById(R.id.switchCompat);
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new AlertDialog.Builder(MainActivity.this, R.style.MyDialog)
.setTitle("Title")
.setMessage("Message")
.show();
}
});
if (AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES)
switchCompat.setChecked(true);
switchCompat.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
InitApplication.getInstance().setIsNightModeEnabled(true);
Intent intent = getIntent();
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
finish();
startActivity(intent);
} else {
InitApplication.getInstance().setIsNightModeEnabled(false);
Intent intent = getIntent();
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
finish();
startActivity(intent);
}
}
});
}
}
В приведенном выше коде мы используем переключатель для переключения между темами дневного и ночного режимов в нашем приложении. Мы сохраняем текущий режим в классе Singleton Pattern for Application. Таким образом, один и тот же экземпляр класса Application может использоваться во всем приложении. Код для класса InitApplication.java
приведен ниже.
package com.journaldev.daynightmode;
import android.app.Application;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
public class InitApplication extends Application {
public static final String NIGHT_MODE = "NIGHT_MODE";
private boolean isNightModeEnabled = false;
private static InitApplication singleton = null;
public static InitApplication getInstance() {
if(singleton == null)
{
singleton = new InitApplication();
}
return singleton;
}
@Override
public void onCreate() {
super.onCreate();
singleton = this;
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
this.isNightModeEnabled = mPrefs.getBoolean(NIGHT_MODE, false);
}
public boolean isNightModeEnabled() {
return isNightModeEnabled;
}
public void setIsNightModeEnabled(boolean isNightModeEnabled) {
this.isNightModeEnabled = isNightModeEnabled;
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = mPrefs.edit();
editor.putBoolean(NIGHT_MODE, isNightModeEnabled);
editor.apply();
}
}
Именно здесь мы обновляем и получаем тип ночного режима из общих настроек.
Вывод приложения поддержки ночного режима Android
Скачать пример проекта темы DayNight для Android