ダークモードをサポートするようにアプリを開発した。ところが、いつダークモードに変更できますか?
アプリで何の設定をしていなかった場合、システムの設定に応じてダークモードに変更されます。 もしユーザーがSettingsでDark modeを有効にしない場合はアプリは常にLight modeで動作するようになります。
もちろん、ユーザーがSettingsの設定を変更しない場合でも、アプリでダークモードを活性化させるメニューを提供することもできます。
この記事では、次の内容につき調べてみます。
- Appでダークモードを有効にする方法
- Settingsでダークモードを有効にする方法
Settingsでダークモードを有効にする方法
DarkModeは [Settings -> Display -> DarkTheme]
で設定することができます。
またはStatusBarのQuickPannelで簡単に有効、無効にすることができます。
システムの設定が変更されるたびに、私のアプリがDark modeで動作したり、Light modeで動作します。
Scheduleオプション
Settingsで Dark theme
に入ると、より細かい設定をすることができます。
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_MASK
にuiMode
をマスキングして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
- Android - 振動、Vibrator、VibrationEffectの例
- Android - TabLayoutの実装方法(+ ViewPager2)
- Android - PackageManagerにPackage情報を取得する
- Android - ACTION_BOOT_COMPLETEDイベント受信
- Android - FusedLocationProviderClientに位置情報を取得する
- Android - GPS、Network位置情報を取得する(LocationManager)
- Android - Foreground Service実行
- Android - 時間、日付、変更イベント受信
- Android - currentTimeMillis()、elapsedRealtime()、uptimeMillis()
- Android-PowerManager WakeLock
- Android - ファイル入出力の例(Read、Write、内部、外部ストレージ)
- Android - Screen On / Offイベントの受信、状態確認
- Android - 他のアプリのServiceにバインド
- Android - Handler vs Executor
- Android - Darkmode有効にする方法
- Android - hasSystemFeature()、サポートされているFeature確認
- Android - アプリの権限を確認(Permission check)
- Android - インストールされてアプリリストをインポートする
- Android App Shortcuts実装
- Android - ContentProviderを実装、および例
- Android - AIDLを利用して、Remote Serviceの実装
- Android - Uri、Scheme、SSP(Scheme Specific Part)説明
- Android - アプリのインストール、削除、イベントダウンロード(BroadcastReceiverインテントを受け取る)
- Android - SharedPreferencesに簡単なデータを保存する方法
- Android - AlarmManagerにアラームを登録する方法、および例
- Android - Quick SettingsにCustom Tile追加する方法(kotlin)
- Android - Broadcast Receiver登録およびイベントの受信方法
- Android - Runtime permissionリクエスト方法と例(kotlin)
- Android - ネットワーク(WIFI)の接続状態を確認し、変更の検出
- Mockito - static、final methodをmockingする方法
- Andriod - カスタムパーミッションを定義する方法
- RobolectricにUnit Testを作成する(kotlin)
- Android Mockitoのテストコードを作成する(kotlin)
- Android - Handlerの使用方法、および例
- Android - IntentService使用方法
- Android - JobIntentService使用方法