ダークモードを実装する

Compose を試す
Jetpack Compose は、Android に推奨される UI ツールキットです。Compose でテーマ設定を操作する方法を学習します。

図 1. ダークモード。

ダークテーマは、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 モードに直接マッピングされています。

テーマを切り替えるには、次の操作を行います。

  • API レベル 31 以降では、次のコマンドを使用します。 UiModeManager#setApplicationNightMode アプリが動作しているテーマをシステムに通知します。これにより スプラッシュ画面のテーマを選択します。

  • API レベル 30 以下では、次のコマンドを使用します。 AppCompatDelegate.setDefaultNightMode() テーマを切り替えます。

で確認できます。

フォースダーク

Android 10 では、フォースダークというデベロッパー向けの機能が提供されています。 DayNight テーマを明示的に設定せずにダークモードをすばやく実装できます。

フォースダークは、ライトモードのアプリの各ビューを分析し、ダークモードを適用します 画面に描画される前に自動的に作成されます。フォースダークと ネイティブ実装を使用して、ダーク できます。

アプリは、android:forceDarkAllowed="true" を設定してフォースダークにオプトインする必要があります。 選択することもできます。この属性は、すべてのシステムおよび AndroidX に用意されているライトテーマ(Theme.Material.Light など)。Google フォースダークで、アプリを徹底的にテストし、必要に応じてビューを除外します。

アプリでダークモード(Theme.Material など)を使用している場合、フォースダークは 適用されました。同様に、アプリのテーマが DayNight テーマから継承している場合、Force は テーマが自動的に切り替わるため、ダークモードは適用されません。

ビューで強制ダークを無効にする

特定のビューのフォースダークは、 android:forceDarkAllowed レイアウト属性、または setForceDarkAllowed()

ウェブ コンテンツ

ウェブベースのコンテンツでダークテーマを使用する方法については、WebView のウェブ コンテンツにダークテーマを適用するをご覧ください。ダークモードの例として、 適用される場合は、WebView のデモを GitHub をタップします。

おすすめの方法

以下のセクションでは、ダークテーマの実装に関するおすすめの方法を紹介します。

通知とウィジェット

デバイスに表示されるが直接制御しない UI サーフェスについては、 使用するビューがすべてホストアプリのテーマを反映していることを確認してください。たとえば 通知とランチャーウィジェットを利用できます

通知

システム提供の通知テンプレート(MessagingStyle など)を使用します。この システムは、正しいビュー スタイルを適用する役割を担います。

ウィジェットとカスタム通知ビュー

ランチャー ウィジェットの場合、またはアプリでカスタム通知コンテンツ ビューを使用している場合は、 ライトモードとダークモードの両方でコンテンツをテストします。

注意すべき一般的な注意点は次のとおりです。

  • 背景色は常に明るいと仮定します。
  • テキストの色をハードコードする。
  • デフォルトのテキスト色を使用しながら、ハードコードされた背景色を設定する。
  • 静的な色のドローアブル アイコンを使用する。

いずれの場合も、ハードコードする代わりに適切なテーマ属性を使用してください。 できます。

起動画面

アプリの起動画面がカスタムの場合は、画面を変更する必要があります。 選択したテーマが反映されます。

プログラムで設定された背景色など、ハードコードされた色をすべて削除します。 白。代わりに ?android:attr/colorBackground テーマ属性を使用してください。

構成の変更

システム設定または AppCompat によってアプリのテーマが変更されると、 uiMode をトリガーする 自動的に適用されます。この場合、アクティビティは自動的に再作成されます。

場合によっては、アプリで構成の変更を処理したいことがあります。たとえば、動画の再生中に構成の変更を遅延させる場合などです。

アプリは、ダークモードごとに次のように宣言することで、ダークモードの実装を処理できます。 ActivityuiMode の構成変更を処理できます。

<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;
}