ダークテーマは、Android 10(API レベル 29)以上で利用可能です。これには次のような利点があります。
- デバイスの画面技術に応じて、電力使用量を大幅に削減します。
- 視力の低いユーザーや明るい光に敏感なユーザーにとって、画面の見やすさが向上します。
- 暗い場所でデバイスを使用しやすくなります。
ダークモードは、Android システムの UI とデバイスで実行されているアプリに適用されます。
Android 10 以降では、次の 3 つの方法でダークモードを有効にできます。
- [設定] > [ディスプレイ] > [テーマ] に移動してシステム設定を使用し、ダークモードを有効にします。
- クイック設定タイルを使用して、通知トレイからテーマを切り替えます(有効になっている場合)。
- Google Pixel デバイスでは、バッテリー セーバー モードを有効にして、ダークモードを同時に有効にします。他のデバイスはこの動作に対応していない可能性があります。
WebView コンポーネントを使用してウェブベースのコンテンツにダークテーマを適用する手順については、WebView のウェブ コンテンツをダークテーマ化するをご覧ください。
アプリでダークモードをサポートする
ダークモードをサポートするには、アプリのテーマ(通常は res/values/styles.xml
にあります)を DayNight
テーマから継承するように設定します。
<style name="AppTheme" parent="Theme.AppCompat.DayNight">
マテリアル コンポーネントのダークテーマを使用することもできます。
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight">
これにより、アプリのメインテーマがシステムが制御する夜間モードのフラグに関連付けられ、有効な場合はデフォルトのダークモードがアプリに設定されます。
テーマとスタイル
ハードコードされた色やアイコンは、ライトモードで使用することは避けてください。代わりに、テーマ属性または夜間限定のリソースを使用してください。
ダークモードでは次の 2 つのテーマ属性が重要です。
?android:attr/textColorPrimary
: 汎用のテキストの色。ライトモードでは黒に近い色、ダークモードでは白に近い色です。この属性には「無効」状態もあります。?attr/colorControlNormal
: 汎用のアイコンの色。この属性には「無効」状態もあります。
マテリアル デザイン コンポーネントを使用することをおすすめします。テーマ属性 ?attr/colorSurface
や ?attr/colorOnSurface
などのカラーテーマ設定システムを使用すると、適切な色を簡単に利用できます。これらの属性はテーマでカスタマイズできます。
アプリ内でテーマを変更する
アプリの実行中に、ユーザーがアプリのテーマを変更できるようにすることができます。推奨されるオプションは次のとおりです。
- 低
- ダーク
- システムのデフォルト(推奨されるデフォルト オプション)
これらのオプションは AppCompat.DayNight
モードに直接マッピングされます。
ライト:
MODE_NIGHT_NO
。ダーク:
MODE_NIGHT_YES
。システムのデフォルト:
MODE_NIGHT_FOLLOW_SYSTEM
テーマを切り替える手順は次のとおりです。
API レベル 31 以降では、
UiModeManager#setApplicationNightMode
を使用して、アプリが実行されるテーマをシステムに通知します。これにより、システムがスプラッシュ画面のテーマを合わせることができます。API レベル 30 以下では、
AppCompatDelegate.setDefaultNightMode()
を使用してテーマを切り替えます。
強制ダーク
Android 10 には、デベロッパーが DayNight
テーマを明示的に設定しなくてもダークモードをすばやく実装できるフォースダークの機能があります。
Force Dark は、ライトテーマのアプリの各ビューを分析し、画面に描画される前にダークモードを自動的に適用します。フォースダークとネイティブ実装を組み合わせて使用すると、ダークテーマの実装に必要な時間を短縮できます。
アプリは、アクティビティのテーマで android:forceDarkAllowed="true"
を設定して、フォースダークにオプトインする必要があります。この属性は、システムと AndroidX が提供するすべてのライトテーマ(Theme.Material.Light
など)に設定されます。フォースダークを使用する場合は、アプリを十分にテストし、必要に応じてビューを除外してください。
アプリがダークモード(Theme.Material
など)を使用している場合、フォースダークは適用されません。同様に、アプリのテーマが DayNight
テーマを継承している場合、テーマの自動切り替えにより、フォースダークは適用されません。
ビューで強制ダークを無効にする
特定のビューでフォースダークは、android:forceDarkAllowed
レイアウト属性または setForceDarkAllowed()
を使用して制御できます。
ウェブ コンテンツ
ウェブベースのコンテンツでダークテーマを使用する方法については、WebView のウェブ コンテンツにダークテーマを適用するをご覧ください。WebView に適用されるダークモードの例については、GitHub の WebView デモをご覧ください。
おすすめの方法
以下のセクションでは、ダークテーマの実装に関するおすすめの方法を紹介します。
通知とウィジェット
デバイスには表示するが直接制御しない UI サーフェスについては、使用するビューがホストアプリのテーマを反映していることを確認してください。2 つの例として、通知とランチャー ウィジェットがあります。
通知
システムが提供する通知テンプレート(MessagingStyle
など)を使用します。つまり、システムが適切なビューのスタイル設定を適用する役割を担います。
ウィジェットとカスタム通知ビュー
ランチャー ウィジェットの場合、またはアプリでカスタム通知のコンテンツ ビューを使用している場合は、ライトモードとダークモードの両方でコンテンツをテストします。
注意すべきよくある間違いは次のとおりです。
- 背景色が常に明るいと仮定する。
- テキストの色をハードコードする。
- デフォルトのテキスト色を使用する場合に、ハードコードされた背景色を設定する。
- 静的な色のドローアブル アイコンを使用する。
いずれの場合も、ハードコードされた色ではなく、適切なテーマ属性を使用します。
起動画面
アプリにカスタムの起動画面がある場合は、選択したテーマを反映するように画面を変更する必要がある場合があります。
プログラムで白に設定されている背景色など、ハードコードされた色をすべて削除します。代わりに ?android:attr/colorBackground
テーマ属性を使用してください。
構成の変更
システム設定または AppCompat のいずれかによってアプリのテーマが変更されると、uiMode
構成の変更がトリガーされます。つまり、アクティビティは自動的に再作成されます。
場合によっては、アプリで構成の変更を処理したいことがあります。たとえば、動画の再生中に構成の変更を遅延させる場合などです。
アプリでダークモードの実装を処理するには、各 Activity
が uiMode
構成の変更を処理できることを宣言します。
<activity
android:name=".MyActivity"
android:configChanges="uiMode" />
Activity
が構成の変更を処理することを宣言している場合、テーマが変更されると、onConfigurationChanged()
メソッドが呼び出されます。
アプリで現在のテーマを確認するには、次のようなコードを実行します。
Kotlin
val currentNightMode = configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK when (currentNightMode) { Configuration.UI_MODE_NIGHT_NO -> {} // Night mode is not active, we're using the light theme. Configuration.UI_MODE_NIGHT_YES -> {} // Night mode is active, we're using dark theme. }
Java
int currentNightMode = configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK; switch (currentNightMode) { case Configuration.UI_MODE_NIGHT_NO: // Night mode is not active, we're using the light theme break; case Configuration.UI_MODE_NIGHT_YES: // Night mode is active, we're using dark theme break; }