Android端末は自身の置かれている状況を認識して、ユーザーが使い易いように動作を変える仕組みを持ちます。
uiModeのNight(UI_MODE_NIGHT_YES:夜である)とDay(UI_MODE_NIGHT_NO:昼である) は、その「置かれている状況」の一つです。
NightとDayは古くから定義されているモードです。
API29で追加された機能の「Dark Theme」と結びついて、Night Modeの時はDark Themeにする使い方が定番になってしまいました。
その影響でしょうか…
Settingsアプリを見ると、Night Modeの影が薄れて、「Drak Themeにする・しない」が主題に作られています。
しかし、裏にNight Modeが存在していることを忘れてはいけません。
※環境:Android Studio Jellyfish | 2023.3.1
Kotlin 1.9.0
Compose Compiler 1.5.1
androidx.compose.foundation:foundation 1.5.0
目次
Dark Theme(Light Theme)とは
Dark Theme(Light Theme)は、画面の配色を定義したテーマです。
Dark Theme背景を暗い配色にするテーマです。画面の全体的な輝度が抑えられます。
以下の利点があります。
- 暗い場所において、周囲と画面の明暗差を少なくし、目の疲労を軽減する。
- 省電力化(有機ELの場合⇒発光する画素の低減)
背景を明るい配色にするテーマです。画面の全体的な輝度が上げられます。
以下の利点があります。
- 明るい場所において、周囲と画面の明暗差を少なくし、文字を鮮明に見せる。
※昔と比べて近年の表示デバイスは十分明るいので、上記の効果は少ないです。
Night Mode(Day Mode)とは
Night Mode(Day Mode)は、端末の置かれている状況を表すモードです。
Night Mode夜を表すモードです。太陽は沈み、周囲は暗いと判断されます。
Day Mode昼を表すモードです。太陽は昇り、周囲は明るいと判断されます。
両者の関係
ユーザーエクスペリエンス(使い心地)を向上させるために、(a)画面の見やすさを優先して、次のようにするのが普通です。
端末の状況がNight Mode⇒表示をDark Themeに切り替え 端末の状況がDay Mode⇒表示をLight Themeに切り替えまた、(b)アプリの省電力化を優先して、Night/Day Modeに関係なく、表示をDark Themeに固定する場合もあります。
Dark Themeの切り替え
Android Studioが作成するプロジェクトのテンプレートは、isSystemDarkTheme( )関数が出力するフラグ(true:Night Mode、false:Day Mode)に従って、テーマの切り替え(コード中のwhen部)が行われます。
... @Composable fun MyApplicationTheme( darkTheme: Boolean = isSystemInDarkTheme(), // Dynamic color is available on Android 12+ dynamicColor: Boolean = true, content: @Composable () -> Unit ) { val colorScheme = when { dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { val context = LocalContext.current if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) } darkTheme -> DarkColorScheme else -> LightColorScheme } MaterialTheme( colorScheme = colorScheme, typography = Typography, content = content ) }
切り替えはisSystemDarkTheme( )関数の出力のみに依存しています。
Night Modeの切り替え
表はNight Modeの切り替えをまとめたものです。非常に複雑です。
切り替えの結果がisSystemdarkTheme( )関数の出力(true:Night Mode、false:Day Mode)に反映されます。
対象 | 切り替え方法 | API | YES/NO | CUSTOM | AUTO | BEDTIME | BATTERY | SYSTEM | UNSPECIFIED |
---|---|---|---|---|---|---|---|---|---|
システム | (A) Settingsアプリ ⇒Displayページ ※API≧29 | 23~28 | Dark Theme未実装 | ||||||
29 | ○ | × | × | ||||||
30~32 | ○ | ○ | ○ | ||||||
33~34 | ○ | ○ | ○ | ○ | |||||
(B) UiModeManager #setNIghtMode( ) ※API<29 | 23~28 | ○ | ○ | ||||||
29 | アクセス許可が必要 ※2 |
||||||||
30~34 | |||||||||
アプリ | (C) AppCompatDelegate #setDefaultNightMode( ) ※Viewシステム | 23~34 | ○ | △ ※1 | △ ※3 | ○ | ー ※4 |
||
(D) UiModeManager #setApplicationNightMode( ) ※API≧31 | 31~34 | ○ | × ※5 | × ※5 | |||||
Activity | (E) AppCompatDelegate #setLocalNightMode( ) ※Viewシステム | 23~34 | ○ | △ ※1 | △ ※3 | ○ | ○ |
||
なし | 31~34 | ||||||||
○:切り替可能、×:切り替え不可能、△:条件付き、空欄:指定不可能 ※1:非推奨、位置情報のアクセス許可が必要 許可がない場合はハードコード値(Start:22:00、End:06:00) ※2:システムパラメータのアクセス許可(MODIFY_DAY_NIGHT_MODE permission)が必要 ※3:システム全体に同様なモードがない場合に限る ※4:起動時のみ ※5:無視される |
ポイントは、対象により切り替えの方法が異なる点と、タイプにより切り替えの時刻が異なる点です。
切り替えの対象
切り替えの対象は3つに分類できます。影響を受ける範囲が異なります。
- システム:実行中の全てのアプリが影響を受ける
- アプリ :アプリ内の全てのActivityが影響を受ける
- Activity:対象のActivityのみが影響を受ける
切り替えのタイプ
手動の他に、時刻に連動して自動で行うモードがあります。
- YES/NO :手動(YES:Night Mode/NO:Day Mode)
- CUSTOM :指定時刻(Start:Night Mode/End:Day Mode)
- AUTO :暦に従う(日の入:Night Mode/日の出:Day Mode)
- BEDTIME:睡眠時間(就寝:Night Mode/起床:Day Mode)
- BATTERY:バッテリーセーブモードに連動してON(Night Mode)
- SYSTEM :システムの設定に従う ※対象がアプリまたはActivityの場合
- UNSPECIFIED :切り替えない(上書きしない) ※対象がActivityの場合
切り替えの詳細
切り替えの詳細は以下のリンクを参照してください。
関連記事: