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

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

WebView の動作は、 prefers-color-schemecolor-scheme のウェブ標準と相互運用されます。可能であれば、アプリで WebView に表示するウェブ コンテンツを作成する際に、ウェブサイトのダークテーマを定義し、 prefers-color-scheme を実装して、WebView がウェブ コンテンツのテーマをアプリのテーマに合わせられるようにする必要があります。

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

アプリの条件 prefers-color-scheme を使用するウェブ コンテンツ prefers-color-scheme を使用しないウェブ コンテンツ
アプリがライトテーマを使用しており、 isLightThemetrue に設定されているか、設定されていない。 WebView は、コンテンツ作成者が定義したライトテーマでコンテンツをレンダリングします。 WebView は、コンテンツ作成者が定義したデフォルトのスタイルでコンテンツをレンダリングします。
アプリが Force Dark を使用して、 アプリにダークモードをアルゴリズムで適用 している。 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 がレンダリングするウェブ コンテンツにダーク テーマをアルゴリズムで適用できるようにすることができます。

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

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

Force Dark でウェブ コンテンツのアルゴリズムによるダークニングを許可する

アプリがアプリレベルの Force Darkを使用している場合、WebView は 次の条件を満たす場合にウェブ コンテンツにアルゴリズムによるダークニングを適用します。

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

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

Force Dark は、独自のダークテーマを提供しないアプリの下位互換性を確保するために主に提供されています。アプリで Force Dark を使用する場合は、ダークテーマのサポートを追加することをおすすめします

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

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

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

  • ウェブ コンテンツで prefers-color-scheme が使用されていない。
  • ウェブ コンテンツの作成者がダークニングを明示的に無効にしていない。

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

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

アプリでライトテーマとダークテーマを切り替える独自の方法(UI の切り替え可能な要素や、時間ベースの自動選択など)を提供している場合は、FORCE_DARK_ONFORCE_DARK_OFF と組み合わせて使用します。

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

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

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

Jetpack ライブラリの 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's のデフォルト モードでは、ウェブページの prefers-color-scheme メディアクエリを尊重するためにメタタグが必要です。 DARK_STRATEGY_WEB_THEME_DARKENING_ONLY モードで WebView を使用できます。この場合、タグが 省略されていても、WebView は常にメディアクエリを適用します。

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

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

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

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