Android - Darkmode有効にする方法

By JS | Last updated: November 15, 2020

ダークモードをサポートするようにアプリを開発した。ところが、いつダークモードに変更できますか?

アプリで何の設定をしていなかった場合、システムの設定に応じてダークモードに変更されます。 もしユーザーがSettingsでDark modeを有効にしない場合はアプリは常にLight modeで動作するようになります。

もちろん、ユーザーがSettingsの設定を変更しない場合でも、アプリでダークモードを活性化させるメニューを提供することもできます。

この記事では、次の内容につき調べてみます。

  • Appでダークモードを有効にする方法
  • Settingsでダークモードを有効にする方法

Settingsでダークモードを有効にする方法

DarkModeは [Settings -> Display -> DarkTheme]で設定することができます。 settings - darkmode

またはStatusBarのQuickPannelで簡単に有効、無効にすることができます。 statusbar quickpannel darkmode

システムの設定が変更されるたびに、私のアプリがDark modeで動作したり、Light modeで動作します。

Scheduleオプション

Settingsで Dark themeに入ると、より細かい設定をすることができます。 Scheduleボタンを押すと、次のように時間に応じて、自動的にダークモードが有効になり、無効にされるようにすることができます。 settings darkmode schedule

  • Turns on at custom time:ダークモードが設定されている時間を直接指定することができます
  • Turns on from sunset to sunrise:日の出、日没の時間にダークモードが変更されます。日の出、日没の時間は TwilightServiceで取得します

Appでダークモードを有効にする方法

Settingsでダークモードを有効にした場合、すべてのアプリがダークモードで動作します。

デバイスは、Light modeに設定されているときに、 AppCompatDelegate APIを使用すると、私のエプマンダークモードで動作するようにすることができます。

AppCompatDelegate APIは次の3つのオプションを提供しています。

  • Dark modeで同
  • Light modeで同
  • Systemの設定で、同

Dark modeで動作

次のコードの呼び出し時に、アプリは再実行され、(Activity.onCreateが再び呼び出される)Dark modeで動作します。

AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)

Light modeで動作

次のコードの呼び出し時に、アプリは再実行され、(Activity.onCreateが再び呼び出される)Light modeで動作します。

AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)

Systemの設定で動作

次のコードを呼び出す時、System設定でアプリが動作します。

Android10(Q OS)からDarkModeがサポートされているので、Android10以上は MODE_NIGHT_FOLLOW_SYSTEMを設定し、 Android10未満は MODE_NIGHT_AUTO_BATTERYを設定する必要があります。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
    AppCompatDelegate.setDefaultNightMode(
        AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
} else {
    AppCompatDelegate.setDefaultNightMode(
        AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY)
}

Darkmode設定値の確認

getDefaultNightMode()はアプリで setDefaultNightMode()に設定されたモードを返します。

これを利用して、次のように実装すれば、ダークモードがToggleようにすることができます。

if (AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_NO) {
    AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
} else {
    AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
}

DarkMode変更時、アプリ再実行されないように作成

DarkMode設定が変更されると、Systemはアプリを再実行します。 onCreate()が再び呼び出されるようにされ、すべての初期化を再されます。

もし初期化することが多くのアプリの実行がかかるなどの問題がある場合Manifestに configChanges="uiMode"を設定して、再実行されないようにすることができます。

<activity android:name=".MainActivity"
    android:configChanges="uiMode">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

上記のように設定すると、Dark modeが有効になったときのアプリは再実行されず、 Activity.onConfigurationChanged()にConfigurationが変更されたイベントが送出されます。

次のように UI_MODE_NIGHT_MASKuiModeをマスキングしてLight modeのかDark modeのか区別することができます。

override fun onConfigurationChanged(newConfig: Configuration) {
    super.onConfigurationChanged(newConfig)

    val nightMode = newConfig.uiMode and Configuration.UI_MODE_NIGHT_MASK
    when (nightMode) {
        Configuration.UI_MODE_NIGHT_NO -> {
            Log.d("Test", "onConfigurationChanged. UI_MODE_NIGHT_NO")
        }
        Configuration.UI_MODE_NIGHT_YES -> {
            Log.d("Test", "onConfigurationChanged. UI_MODE_NIGHT_YES")
        }
    }
}

この状態で、アプリのUIは変更されていない状態です。 onConfigurationChanged()でイベントを受けて、次のような処理をしてくれるとします。

  • 何もしなければ、UIはDarkModeのリソースに変更されていない
  • 必要な部分だけDarkModeのリソースに変更
  • 現在作業をすべて終えて(Ex。動画視聴)その背後にあるActivityが再実行されるようにのみ

システムによってDarkMode設定が変更されたり、またはAppCompatDelegateマイアプリの設定を変更するとき、すべて onConfigurationChanged()が呼び出されます。

Related Posts

codechachaCopyright ©2019 codechacha