WebView のウェブ コンテンツを暗くする

Android 10 以降では、アプリはダークモードをサポートし、システムテーマに応じてライトモードとダークモードのアプリテーマを自動的に切り替えることができます。現在のアプリのテーマに合わせて、WebView のウェブ コンテンツでもライト、ダーク、デフォルトのスタイルを使用できます。

WebView の動作は、prefers-color-scheme および color-scheme ウェブ標準と相互運用できます。WebView に表示するウェブ コンテンツを作成する場合は、可能な限り、ウェブサイトにダークテーマを定義し、prefers-color-scheme を実装して、WebView がウェブ コンテンツのテーマをアプリのテーマと一致させるようにします。

次の表に、ウェブ コンテンツのスタイルとアプリの条件に応じて、WebView がウェブ コンテンツをアプリでレンダリングする仕組みを示します。

アプリの条件 prefers-color-scheme を使用するウェブ コンテンツ prefers-color-scheme を使用しないウェブ コンテンツ
アプリは isLightThemetrue に設定されているか未設定であるため、ライトモードを使用しています。 WebView は、コンテンツ作成者が定義したライトテーマでコンテンツをレンダリングします。 WebView は、コンテンツの作成者が定義したデフォルトのスタイルでコンテンツをレンダリングします。
アプリがフォースダークを使用して、アプリにアルゴリズムによってダークモードを適用している。 WebView は、コンテンツ作成者が定義したダークモードでコンテンツをレンダリングします。 コンテンツの作成者が許可している場合、WebView はアルゴリズムを使用して生成されたダークモードでコンテンツをレンダリングします。
アプリがダークモードを使用していて、isLightThemefalse に設定されており、WebView のアルゴリズムによるダークニングを許可していない WebView は、コンテンツ作成者が定義したダークモードでコンテンツをレンダリングします。 WebView は、コンテンツの作成者が定義したデフォルトのスタイルでコンテンツをレンダリングします。
アプリがダークモードを使用していて、isLightThemefalse に設定されており、WebView のアルゴリズム ダークニング許可している WebView は、コンテンツ作成者が定義したダークモードでコンテンツをレンダリングします。 コンテンツの作成者が許可している場合、WebView はアルゴリズムを使用して生成されたダークモードでコンテンツをレンダリングします。

コンテンツ作成者のスタイル設定

アプリの isLightTheme 属性は、アプリのテーマがライトかダークかを示します。WebView は、isLightTheme に従って常に prefers-color-scheme を設定します。isLightThemetrue の場合、または指定されていない場合、prefers-color-schemelight です。それ以外の場合、dark になります。

つまり、ウェブ コンテンツが prefers-color-scheme を使用していて、コンテンツ作成者がそれを許可している場合、アプリのテーマに合わせて、コンテンツ作成者が定義したライトモードまたはダークモードが常にウェブ コンテンツに自動的に適用されます。

アルゴリズムによるダークニング

ウェブ コンテンツが prefers-color-scheme を使用しないケースに対応するため、アプリでは、WebView が必要に応じてレンダリングするウェブ コンテンツにダークテーマを適用することを許可できます。

アプリでアプリレベルのフォースダークを使用して、アルゴリズムによってダークモードを適用している場合は、フォースダークを使用してウェブ コンテンツにアルゴリズムによるダークニングを許可する方法についての次のセクションをご覧ください。

アプリでフォースダークを使用していない場合は、WebView でアルゴリズム ダークニングを許可するタイミングをアプリで指定する方法は、アプリの対象 API レベルによって異なります。詳しくは、以下の Android 13 以降をターゲットとするアプリAndroid 12 以前をターゲットとするアプリをご覧ください。

フォースダークを使用してウェブ コンテンツにアルゴリズムによるダークニングを許可する

アプリでアプリレベルのフォースダークを使用している場合、WebView は以下の条件が満たされると、ウェブ コンテンツにアルゴリズム ダークニングを適用します。

  • WebView とその親要素では、フォースダークが許可されます。
  • 現在のアクティビティ テーマはライトとしてマークされ、isLightThemetrue に設定されます。
  • ウェブ コンテンツの作成者はダークニングを明示的に無効にしていません。
  • Android 13(API レベル 33)以降をターゲットとするアプリでは、ウェブ コンテンツで prefers-color-scheme は使用されません。
  • Android 12(API レベル 32)以前をターゲットとするアプリの場合: WebView の forceDarkMode 設定FORCE_DARK_AUTO に設定され、フォースダーク戦略が DARK_STRATEGY_USER_AGENT_DARKENING_ONLY に設定されている。

WebView とそのすべての親は、View.setForceDarkAllowed() を使用してフォースダークを許可できます。デフォルト値は Android テーマの setForceDarkAllowed() 属性から取得されます。この属性も true に設定する必要があります。

強制ダークモードは、独自のダークモードを提供しないアプリの下位互換性を主な目的としています。アプリでフォースダークを使用する場合は、ダークモードのサポートを追加することをおすすめします。

アルゴリズムによるダークニングを許可する(Android 13 以降をターゲットとするアプリ)

アプリレベルのフォースダークを使用せずに、Android 13(API レベル 33)以降をターゲットとするアプリの場合は、AndroidX の setAlgorithmicDarkeningAllowed() メソッドを使用して true を渡し、WebView でアルゴリズムによるダークニングを許可することを指定します。このメソッドには、以前の Android バージョンと下位互換性があります。

WebView は、次の条件が満たされると、アルゴリズムによるダークニングを適用します。

  • ウェブ コンテンツは prefers-color-scheme を使用しません。
  • ウェブ コンテンツの作成者はダークニングを明示的に無効にしていません。

アルゴリズムによるダークニングを許可する(Android 12 以前をターゲットとするアプリ)

アプリレベルのフォースダークを使用せずに、Android 12(API レベル 32)以前をターゲットとするアプリでは、FORCE_DARK_ON を使用してアルゴリズムによるダークニングを許可します。

UI の切り替え可能な要素や時間ベースの自動選択など、ライトモードとダークモードを切り替える独自のメソッドがアプリに用意されている場合は、FORCE_DARK_ONFORCE_DARK_OFF とともに使用します。

この機能がサポートされているかどうかを確認するには、Activity.onCreate などの WebView オブジェクトを設定する場所に次のコード行を追加します。

Kotlin

if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
    WebSettingsCompat.setForceDark(...)
}

Java

if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
    WebSettingsCompat.setForceDark(...);
}

アプリがシステム環境設定の変更の検出に依存している場合は、テーマの変更を明示的にリッスンし、FORCE_DARK_ON および FORCE_DARK_OFF 状態の WebView に適用する必要があります。

次のコード スニペットは、テーマの形式を変更する方法を示しています。

Kotlin

if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
    when (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) {
        Configuration.UI_MODE_NIGHT_YES -> {
            WebSettingsCompat.setForceDark(myWebView.settings, FORCE_DARK_ON)
        }
        Configuration.UI_MODE_NIGHT_NO, Configuration.UI_MODE_NIGHT_UNDEFINED -> {
            WebSettingsCompat.setForceDark(myWebView.settings, FORCE_DARK_OFF)
        }
        else -> {
            //
        }
    }
}

Java

if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
    switch (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) {
        case Configuration.UI_MODE_NIGHT_YES:
            WebSettingsCompat.setForceDark(myWebView.getSettings(), FORCE_DARK_ON);
            break;
        case Configuration.UI_MODE_NIGHT_NO:
        case Configuration.UI_MODE_NIGHT_UNDEFINED:
            WebSettingsCompat.setForceDark(myWebView.getSettings(), FORCE_DARK_OFF);
            break;
    }
}

ダークモードの処理をカスタマイズする

また、AndroidX の ForceDarkStrategy API を使用して、特定の WebView へのダークニングの適用方法を制御することもできます。この API は、フォースダークが FORCE_DARK_ON または FORCE_DARK_AUTO に設定されている場合にのみ適用されます。

この API を使用すると、アプリはウェブテーマ ダークニングまたはユーザー エージェント ダークニングのいずれかを使用できます。

  • ウェブテーマのダークニング: ウェブ デベロッパーは、@media (prefers-color-scheme: dark) を適用して、ダークモードでのウェブページの外観を制御できます。WebView は、これらの設定に従ってコンテンツをレンダリングします。ウェブテーマのダークニングについて詳しくは、仕様をご覧ください。
  • ユーザー エージェントのダークニング: WebView によってウェブページの色が自動的に反転されます。ユーザー エージェント ダークニングを使用する場合、@media (prefers-color-scheme: dark) クエリは false と評価されます。

2 つの方法のどちらかを選択するには、次の API を使用します。

Kotlin

if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK_STRATEGY)) {
    WebSettingsCompat.setForceDarkStrategy(...)
}

Java

if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK_STRATEGY)) {
    WebSettingsCompat.setForceDarkStrategy(...);
}

サポートされている戦略オプションは次のとおりです。

  • DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING: これはデフォルトのオプションです。ほとんどのブラウザでは <meta name="color-scheme" content="dark light"> タグはオプションとして扱われますが、Android WebView のデフォルト モードでは、ウェブページの prefers-color-scheme メディアクエリを尊重するためにメタタグが必要です。WebView は DARK_STRATEGY_WEB_THEME_DARKENING_ONLY モードで使用できます。この場合、タグが省略されていても、WebView は常にメディアクエリを適用します。

    ただし、デフォルト構成の WebView でコンテンツが正しくレンダリングされるように、ウェブ デベロッパーはウェブサイトに <meta name="color-scheme" content="dark light"> タグを追加することをおすすめします。

  • DARK_STRATEGY_USER_AGENT_DARKENING_ONLY: 「ユーザー エージェント ダークニング」と呼ばれます。WebView はウェブページのダークニングを無視し、自動ダークニングを適用します。

prefers-color-scheme メディアクエリでカスタマイズしたファースト パーティのウェブ コンテンツをアプリに表示する場合は、DARK_STRATEGY_WEB_THEME_DARKENING_ONLY で WebView がカスタムテーマを使用するようにすることをおすすめします。

ダークモードの適用例については、GitHub の WebView デモをご覧ください。