追記: 20191017
Android 10ではコントロールセンターからダークモードが切り替え可能になり「システムに従う」「バッテリー状態によって切り替える」設定が追加されました。くわしくはこちら
追記: 20190509
Google I/O 2019で公式のダークテーマのデザインガイドラインとオンライン学習ページが公開されました。
- https://material.io/design/color/dark-theme.html
- https://codelabs.developers.google.com/codelabs/design-material-darktheme/
はじめに
去年末にQiitaに投稿した「スマホアプリ開発者のための2018年動向まとめ」でダークモードについて少し書いたのですが、2019年になってからダークモードのニュースが増えているような気がします。
今風の表現で言えば2019年は"ダークモード元年"になりそうな予感(?)です..!
↓Androidでダークモード?
Android Qの初期ビルドが出回る。噂のダークモードに加え、DeX的なデスクトップモードも搭載か
https://japanese.engadget.com/2019/01/17/android-q-dex/
↓iOSもダークモード??
iOS 13でついにiPhoneにダークモードが登場か、バッテリー消費を劇的に抑えられるかも
http://gigazine.net/news/20190203-ios-13-dark-mode/
↓Chromeでもダークモード???
Chrome Canary now supports dark mode in Windows 10 and respects light/dark mode Setting
https://techdows.com/2019/02/chrome-canary-now-supports-dark-mode-in-windows-10-and-respects-light-dark-mode-setting.html
個人的に出しているニュースリーダーアプリにも1月にダークモードを実装したので
そのときに得たデザインのノウハウや実装方法についてまとめます。
デザインについて
ダークモードの色について
Android Deveopers スタイルとテーマ
https://developer.android.com/guide/topics/ui/themes?hl=ja
Androidのテーマには大きく黒背景(Dark)と白背景(Light)があります。
コンポーネントごとに個別のカラー設定も可能ですが、
通常はThemeとしてカラーなどの表示をまとめて設定します。
<resources>
    <!-- styleでテーマを書いていきます -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar" />
    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>
</resources>
:
        <!-- android:themeで使用するテーマを指定します -->
        <activity
                android:name=".MainActivity"
                android:label="@string/app_name"
                android:theme="@style/AppTheme.NoActionBar">
:
Android Studioでプロジェクトを作成するとデフォルトとしてTheme.AppCompat.Light.DarkActionBarが設定されています。
一切設定をしていない素のTheme.AppCompat.Light の画面キャプチャは以下となります。
<resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light" />
</resources>
 
<resources>
    <style name="AppTheme" parent="Theme.AppCompat" />
</resources>
 
上記の色はサポートライブラリの以下xmlが使用されています。
colors_material.xml
https://chromium.googlesource.com/android_tools/+/HEAD/sdk/extras/android/support/v7/appcompat/res/values/colors_material.xml
カラーコードを表にしてまとめると以下のようになります。
(xml上はARGBカラーコード表記ですが、QiitaにRGBカラーコード表示機能があるためA100%のものはRGBに省略しました)
| material_dark | material_light | |
|---|---|---|
| foreground | #ffffff(white) | #000000(black) | 
| background | #303030(grey_850) | #fafafa(grey_50) | 
| background_floating | #424242(grey_800) | #ffffff(white) | 
| primary | #212121(grey_900) | #f5f5f5(grey_100) | 
| primary_dark | #000000(black) | #757575(grey_600) | 
| ripple | #33ffffff | #1f000000 | 
| accent | #80cbc4(deep_teal_200) | #009688(deep_teal_500) | 
| button | #5a595b | #d6d7d7 | 
| primary_text_default | #ffffffff | #de000000 | 
| secondary_text_default | #b3ffffff | #8a000000 | 
Material Design / The color system
https://material.io/design/color/the-color-system.html
上記Material Designサイトでは表記されていないgrey_850なども使用されています。
Floating Action Buttonにも使用されているaccentカラーは
lightでは500ベース, darkでは200ベースがデフォルトのようです。
ダークモードのアイコンについて
YouTubeやTwitterでアイコンが表示されていますが共通しているのは欠けた月をモチーフとしています。
YouTubeはMaterial Designの brightness_4 を使用しています。
Twitterの右上が欠けた月はMaterial Designにないオリジナルのアイコンです。
Material Design / Icons
https://material.io/tools/icons/
私は個人のアプリでは brightness_2 を使用しました。
Material Designサイトの以下のあたりがおすすめです。
開発について
夜間モードリソースを使う実装方法がオススメ
Theme切り替えはいくつかの実装方法がありますが、「夜間モード」を用いると簡潔に行うことができます。
Androidでは2010年に公開されたAndroid2.2(v8)からカーナビアプリ・デスクトップ向けアプリ向けに、
夜のみDarkテーマを使用する「夜間モード」があります。
リソースの提供 - 夜間モード
https://developer.android.com/guide/topics/resources/providing-resources#NightQualifier
Android Developers Documentation - UiModeManager
https://developer.android.com/reference/android/app/UiModeManager#setNightMode(int)
リソース末尾に-nightを付与することで昼間向けテーマと夜間向けテーマを設定することができます。
- res/values/themes.xml
- res/values-night/themes.xml
上記の「夜間モード」はAndroid6.0(v23)からモバイルアプリでも使用できるようになりました。
切替方法は後述します。
DayNightテーマ
Medium - Android Developers "AppCompat — DayNight"
https://medium.com/androiddevelopers/appcompat-v23-2-daynight-d10f90c83e94
夜間モード切り替えは全体であればAppCompatDelegate.setDefaultNightMode()特定のAppCompat内であればAppCompatDelegate.setLocalNightMode()で行います。
Android9からは「システム設定に従う」が追加され、デフォルト設定になっています。
AppCompatDelegate.setDefaultNightMode()
- MODE_NIGHT_NO. Always use the day (light) theme.
- MODE_NIGHT_YES. Always use the night (dark) theme.
- MODE_NIGHT_AUTO - !!Soon to be deprecated!!
- MODE_NIGHT_FOLLOW_SYSTEM (default). This setting follows the system’s setting, which on Android Pie and above is a system setting (more on this below).
また、昼間であればTheme.AppCompat.Light、夜であればTheme.AppCompatを使用するDayNightテーマがサポートライブラリのv23から追加されています。
<style name="MyTheme" parent="Theme.AppCompat.DayNight">
</style>
ユーザが自発的に夜間モードテーマを切り替える場合、
切り替え後は Activity#recreate()を呼び出すとテーマが適応されます。
【補足】MaterialComponent.DayNightテーマ
Medium - Android Developers "DayNight — Adding a dark mode to your app"
https://medium.com/androiddevelopers/appcompat-v23-2-daynight-d10f90c83e94
ちょうどこの記事を書いていた2019年2月に上記のMediumが更新されました..!
タイトルもダークモード関連に変更..!
Just updated my (now 3 years old) blog post on AppCompat's DayNight support for dark themes ⚫⚪. It should now be up-to-date, and talks about a few changes coming out soon.https://t.co/dkGU7MTWvP
— Chris Banes (@chrisbanes) 2019年2月22日
ざっくりと変更点は
Theme.MaterialComponents.DayNight が 1.1.0 から使える。
AppCompatDelegate.setDefaultNightMode()でMODE_AUTOは非推奨にする。
とのことです。
個人的な感想
実際に開発して画面を見比べてみて、ダークモード実装が映えるのは
値段の高い端末よりも安価なディスプレイを搭載した端末のように感じました。
Android Go端末やノングレア液晶のChromebookだと白背景よりも黒背景のほうが格段に見やすくなったように感じます。
個人的に、去年にダークモードがない理由でアプリに低レビューをいただいた事がありました。。
今年以降、ダークテーマがアプリの必須機能かのようになる可能性もあります。。
ダークモードの実装は容易ですが、Colorの整理に時間が取られました。
リソースの整理は日頃やっておくと良いかもしれません。
おわり。





