言いたいことはそれだけか

KotlinとかAndroidとかが好きです。調べたことをメモします。٩( 'ω' )و

Androidのdark theme

Androidのdark themeをさわってみたのでメモを残す。

Dark themeとは?

公式documentはこちら

developer.android.com

電池の節約だったり、low visionなuser向けにより良いUIを提供することを目的に、黒背景のthemeがAndroid Q からサポートされた。

アプリでDark themeに対応する

App Theme

まずはApplicationのThemeのparentをDayNightにする

<style name="AppTheme" parent="Theme.AppCompat.DayNight">

もしくはMaterialComponentsの方を使ってもいいらしい。

<style name="AppTheme" parent="Theme.MaterialComponents.DayNight">

MaterialComponentsの方がいい感じに色をそれっぽく自動で変えてくれる気がする。 (ActionBarのcolorPrimaryの色とかbuttonとか。)

Resource

dark themeがONになっているときは基本的にvalues-night などnightのqualifierがついたresource directoryに置いているものが読まれる。 (values-notnight も作ることができる。defaultをdark themeにしたいときはこれを使えば良さそう。)

dark themeで変えなきゃいけないのはcolorとアイコンくらいかなぁ。

f:id:muumuumuumuu:20190608155245p:plain

ちなみにdark themeは端末のSettings > Display > Dark Theme からONにすることができる。 Qより前のOS(Pieとか)でも同じメニューが存在するが、ONにしても values-night 配下のリソースが使われないので注意。

Dark themeを動的に切り替える

端末のDark Themeの設定ではなく、アプリ固有でDark Themeを設定することもできる。

例えば端末の設定に関わらず、アプリ全体でDark ThemeをONにしたいときは下記のような1行を呼んでやれば良い。

AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_YES)

アプリ全体ではなく、Activity単位でDark ThemeをONにしたいときは下記のような1行を呼んでやれば良い。

// Call this from AppCompatActivity
delegate.localNightMode = MODE_NIGHT_YES

引数に使える定数は以下(deprecatedなものは除く)

const values description
MODE_NIGHT_AUTO_BATTERY 3 システムの Battery Saver 機能が有効のときはdark modeを使って、それ以外はlight modeになる。
MODE_NIGHT_FOLLOW_SYSTEM 0 システムの night modeに従う。
MODE_NIGHT_NO 1 常にlight modeを使う。また、notnight qualified resourcesが時間に関わらず(夜中でも)使われる。
MODE_NIGHT_UNSPECIFIED 100 night modeをunspecifiedしたい時に使う。主にsetLocalNightMode() でdefaultのnight modeに戻したい時に使うっぽい。
MODE_NIGHT_YES 2 常にdark modeを使う。また、 night qualified resourcesが時間に関わらず(昼間でも)使われる。

おまけ

実装だけではなく、material designとしてのdark themeの考え方も読んでみると面白い。 背景(elevation = 0)は黒なんだけど、Surface (elevation = 1)は黒みがかった灰色。dark modeはelevationを影の強さで表現することができないので、高いelevationになるほど白みがかって行くことで表現しているらしい。なるほど。 material.io