これからAndroidでダークモードを実装するエンジニア/デザイナ向け資料


追記: 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としてカラーなどの表示をまとめて設定します。

style.xml
<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>

AndroidManifest.xml
:
        <!-- 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 の画面キャプチャは以下となります。

style.xml
<resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light" />
</resources>

style.xml
<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/

YouTubeのアイコン

Twitterのアイコン

私は個人のアプリでは 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から追加されています。

theme.xml
<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が更新されました..!
タイトルもダークモード関連に変更..!

ざっくりと変更点は
Theme.MaterialComponents.DayNight1.1.0 から使える。
AppCompatDelegate.setDefaultNightMode()MODE_AUTOは非推奨にする。
とのことです。

個人的な感想

実際に開発して画面を見比べてみて、ダークモード実装が映えるのは
値段の高い端末よりも安価なディスプレイを搭載した端末のように感じました。
Android Go端末やノングレア液晶のChromebookだと白背景よりも黒背景のほうが格段に見やすくなったように感じます。

個人的に、去年にダークモードがない理由でアプリに低レビューをいただいた事がありました。。
今年以降、ダークテーマがアプリの必須機能かのようになる可能性もあります。。

ダークモードの実装は容易ですが、Colorの整理に時間が取られました。
リソースの整理は日頃やっておくと良いかもしれません。

おわり。