Przyciemnianie treści z internetu w komponencie WebView

Na Androidzie 10 i nowszych aplikacja może obsługiwać ciemny motyw i automatycznie przełączać się między jasnym i ciemnym motywem aplikacji w zależności od motywu systemowego. Aby dopasować się do bieżącego motywu aplikacji, treści internetowe w WebView mogą też mieć styl jasny, ciemny lub domyślny.

Działanie komponentu WebView współpracuje ze standardami internetowymi prefers-color-scheme i color-scheme. Jeśli tworzysz treści internetowe, które chcesz wyświetlać w komponencie WebView, w miarę możliwości musisz zdefiniować ciemny motyw witryny i zaimplementować prefers-color-scheme, aby komponent WebView mógł dopasować motyw treści internetowej do motywu aplikacji.

W tabeli poniżej opisujemy, jak WebView renderuje treści internetowe w aplikacji w zależności od stylu tych treści i warunków aplikacji:

Warunki aplikacji Treści internetowe wykorzystujące prefers-color-scheme Treści internetowe, które nie korzystają z tagu prefers-color-scheme
Aplikacja używa jasnego motywu, w którym atrybut isLightTheme ma wartość true lub nie jest on ustawiony. WebView renderuje treści z użyciem jasnego motywu zdefiniowanego przez autora. WebView renderuje treści zgodnie z domyślnym stylem zdefiniowanym przez autora treści.
Aplikacja korzysta z ustawienia Wymuś ciemny motyw, aby algorytmicznie zastosować do niej ciemny motyw. WebView renderuje treści z użyciem ciemnego motywu określonego przez autora. Jeśli autor treści zezwoli na to, komponent WebView renderuje treści z użyciem ciemnego motywu generowanego za pomocą algorytmu.
Aplikacja używa ciemnego motywu z parametrem isLightTheme ustawionym jako false oraz nie zezwala na algorytmiczne przyciemnianie przez komponent WebView. WebView renderuje treści z użyciem ciemnego motywu określonego przez autora. WebView renderuje treści zgodnie z domyślnym stylem zdefiniowanym przez autora treści.
Aplikacja używa ciemnego motywu, w którym isLightTheme ma wartość false, a zezwala ona na algorytmiczne przyciemnianie przez WebView. WebView renderuje treści z użyciem ciemnego motywu określonego przez autora. Jeśli autor treści zezwoli na to, komponent WebView renderuje treści z użyciem ciemnego motywu generowanego za pomocą algorytmu.

Styl autora treści

Atrybut isLightTheme aplikacji wskazuje, czy motyw aplikacji jest jasny czy ciemny. WebView zawsze ustawia prefers-color-scheme zgodnie z isLightTheme. Jeśli isLightTheme ma wartość true lub nie jest określony, prefers-color-scheme ma wartość light. W przeciwnym razie jest to dark.

Oznacza to, że jeśli treść internetowa korzysta z elementu prefers-color-scheme, a jego autor na to zezwala, jasny lub ciemny motyw zdefiniowany przez niego jest zawsze automatycznie stosowany do treści internetowych, aby pasował do motywu aplikacji.

Zaciemnianie za pomocą algorytmu

Aby uwzględnić przypadki, w których treści internetowe nie korzystają z prefers-color-scheme, aplikacja może zezwalać komponentowi WebView na stosowanie w razie potrzeby algorytmicznego zastosowania ciemnego motywu do renderowanych treści.

Jeśli Twoja aplikacja korzysta z funkcji Wymuś ciemny motyw na poziomie aplikacji, aby za pomocą algorytmu zastosować ciemny motyw, zapoznaj się z sekcją poniżej, aby dowiedzieć się, jak zezwolić na przyciemnienie algorytmem w przypadku treści internetowych za pomocą wymuszenia ciemnego.

Jeśli w aplikacji nie jest włączone wymuszanie ciemnych zmian, to sposób, w jaki aplikacja ma zezwalać na przyciemnianie za pomocą algorytmu w komponencie WebView, zależy od jej docelowego poziomu interfejsu API. Więcej informacji znajdziesz w sekcjach poniżej dotyczących aplikacji kierowanych na Androida 13 lub nowszego oraz aplikacji kierowanych na Androida 12 lub starszego.

Zezwalaj na przyciemnianie za pomocą algorytmu w przypadku treści internetowych dzięki wymuszeniu ciemnego

Jeśli Twoja aplikacja korzysta z opcji Wymuś ciemny ekran na poziomie aplikacji, WebView stosuje algorytmiczne przyciemnienie treści na stronie, o ile są spełnione te warunki:

  • Komponent WebView i jego elementy nadrzędne pozwalają wymusić ciemny ekran.
  • Bieżący motyw aktywności jest oznaczony jako jasny, a parametr isLightTheme ma wartość true.
  • Autor treści internetowych nie wyłącza wyraźnie funkcji przyciemniania.
  • W przypadku aplikacji kierowanych na Androida 13 (poziom interfejsu API 33) lub nowszego treści z internetu nie używają parametru prefers-color-scheme.
  • W przypadku aplikacji kierowanych na Androida w wersji 12 (poziom interfejsu API 32) lub starszego: ustawienie WebView w forceDarkMode ma wartość FORCE_DARK_AUTO, a strategia wymuszania trybu ciemnego to DARK_STRATEGY_USER_AGENT_DARKENING_ONLY.

WebView i jego wszystkie elementy nadrzędne mogą zezwalać na wymuszanie ciemności za pomocą View.setForceDarkAllowed(). Wartość domyślna pochodzi z atrybutu setForceDarkAllowed() motywu Androida, który też musi być ustawiony na true.

Wymuszanie trybu ciemnego jest udostępniane głównie na potrzeby zgodności wstecznej w aplikacjach, które nie mają własnego ciemnego motywu. Jeśli Twoja aplikacja używa wymuszania trybu ciemnego, zalecamy dodanie obsługi ciemnego motywu.

Zezwalaj na przyciemnianie za pomocą algorytmów (aplikacje kierowane na Androida 13 lub nowszego)

W przypadku aplikacji, które nie korzystają z wymuszania trybu ciemnego na poziomie aplikacji, ale są kierowane na Androida 13 (poziom interfejsu API 33) lub nowszego, użyj metody AndroidX setAlgorithmicDarkeningAllowed() i przekaż w true, że komponent WebView powinien zezwalać na ściemnianie za pomocą algorytmów. Ta metoda ma zgodność wsteczną z poprzednimi wersjami Androida.

Następnie komponent WebView stosuje algorytmiczne przyciemnianie, jeśli są spełnione te warunki:

  • Treści z internetu nie używają elementu prefers-color-scheme.
  • Autor treści internetowych nie wyłącza wyraźnie funkcji przyciemniania.

Zezwalaj na przyciemnianie za pomocą algorytmów (aplikacje kierowane na Androida 12 lub starszego)

W przypadku aplikacji, które nie korzystają z wymuszania trybu ciemnego na poziomie aplikacji i są kierowane na Androida w wersji 12 (poziom interfejsu API 32) lub niższego, użyj wartości FORCE_DARK_ON, aby zezwolić na przyciemnianie stosowane przez algorytm.

Użyj atrybutu FORCE_DARK_ON w połączeniu z FORCE_DARK_OFF, jeśli aplikacja ma własną metodę przełączania między jasnymi i ciemnymi motywami, np. element z możliwością przełączania lub automatyczny wybór na podstawie czasu.

Aby sprawdzić, czy ta funkcja jest obsługiwana, dodaj te wiersze kodu niezależnie od tego, gdzie konfigurujesz obiekt WebView, na przykład w Activity.onCreate:

Kotlin

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

Java

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

Jeśli aplikacja wykrywa zmiany preferencji systemowych, powinna wykrywać zmiany motywu i stosować je do komponentu WebView ze stanami FORCE_DARK_ON i FORCE_DARK_OFF.

Ten fragment kodu pokazuje, jak zmienić format motywu:

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

Dostosowywanie obsługi ciemnego motywu

Możesz też użyć interfejsu ForceDarkStrategy API w AndroidzieX, aby określić sposób stosowania przyciemnienia do danego komponentu WebView. Ten interfejs API ma zastosowanie tylko wtedy, gdy ustawienie wymuszania ciemności ma wartość FORCE_DARK_ON lub FORCE_DARK_AUTO.

Dzięki interfejsowi API aplikacja może stosować przyciemnianie motywu internetowego lub przyciemnianie klienta użytkownika:

  • Zaciemnianie motywów stron internetowych: deweloperzy stron internetowych mogą zastosować @media (prefers-color-scheme: dark), aby kontrolować wygląd stron w trybie ciemnym. WebView renderuje treści zgodnie z tymi ustawieniami. Więcej informacji o przyciemnianiu motywu internetowego znajdziesz w specyfikacji.
  • Przyciemnianie klienta użytkownika: komponent WebView automatycznie odwraca kolory strony internetowej. Jeśli korzystasz z ciemnienia klienta użytkownika, zapytanie @media (prefers-color-scheme: dark) zwraca wartość false.

Aby wybrać jedną z tych strategii, użyj tego interfejsu API:

Kotlin

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

Java

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

Obsługiwane opcje to:

  • DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING: to jest opcja domyślna. Większość przeglądarek traktuje tag <meta name="color-scheme" content="dark light"> jako opcjonalny, ale domyślny tryb Android WebView wymaga, by metatag uwzględniał zapytania o multimedia przeznaczone dla strony internetowej prefers-color-scheme. Możesz używać komponentów WebView w trybie DARK_STRATEGY_WEB_THEME_DARKENING_ONLY. W takim przypadku WebView zawsze stosuje zapytania o multimedia nawet wtedy, gdy tag jest pominięty.

    Zalecamy jednak deweloperom stron internetowych dodanie tagu <meta name="color-scheme" content="dark light"> do witryn, aby mieć pewność, że treść będzie prawidłowo renderowana przez komponenty WebView z konfiguracją domyślną.

  • DARK_STRATEGY_USER_AGENT_DARKENING_ONLY: Nazywa się „ciemnieniem klienta użytkownika” – komponent WebView ignoruje przyciemnienie strony internetowej i stosuje automatyczne przyciemnianie.

Jeśli Twoja aplikacja wyświetla własne treści z internetu dostosowane przez Ciebie za pomocą zapytania o multimedia prefers-color-scheme, zalecamy DARK_STRATEGY_WEB_THEME_DARKENING_ONLY, aby komponent WebView korzystał z motywu niestandardowego.

Przykład zastosowanego ciemnego motywu znajdziesz w prezentacji WebView na GitHubie.