Làm tối nội dung trên web trong WebView

Trong Android 10 trở lên, ứng dụng có thể hỗ trợ Giao diện tối và tự động thay đổi giữa giao diện sáng và tối của ứng dụng theo giao diện của hệ thống. Để khớp với giao diện ứng dụng hiện tại, nội dung trên web trong WebView cũng có thể sử dụng kiểu sáng, tối hoặc mặc định.

Hành vi của WebView tương tác với prefers-color-schemecolor-scheme web. Bất cứ khi nào có thể, nếu bạn tạo nội dung trên web mà bạn muốn để ứng dụng của bạn hiển thị trong WebView, bạn nên xác định giao diện tối cho trang web và triển khai prefers-color-scheme để WebView có thể khớp với cho giao diện của ứng dụng.

Bảng sau đây mô tả cách WebView hiển thị nội dung trên web trong ứng dụng của bạn, tuỳ thuộc vào kiểu của nội dung web và điều kiện của ứng dụng:

Các điều kiện về ứng dụng Nội dung web sử dụng prefers-color-scheme Nội dung web không sử dụng prefers-color-scheme
Ứng dụng đang dùng giao diện sáng với isLightTheme được đặt thành true hoặc chưa được đặt. WebView hiển thị nội dung với giao diện sáng tác giả nội dung đã xác định. WebView hiển thị nội dung với kiểu mặc định do tác giả nội dung.
Ứng dụng đang sử dụng Ưu tiên chế độ tối đến áp dụng giao diện tối bằng thuật toán cho ứng dụng. WebView hiển thị nội dung với giao diện tối tác giả nội dung đã xác định. Nếu được tác giả nội dung cho phép, WebView sẽ hiển thị nội dung đó bằng giao diện tối được tạo bằng thuật toán.
Ứng dụng đang dùng giao diện tối với isLightTheme được đặt thành false và ứng dụng không cho phép thuật toán làm tối cho WebView. WebView hiển thị nội dung với giao diện tối tác giả nội dung đã xác định. WebView hiển thị nội dung với kiểu mặc định do tác giả nội dung.
Ứng dụng đang dùng giao diện tối với isLightTheme được đặt thành false và ứng dụng có cho phép Chế độ làm tối dựa trên thuật toán cho WebView. WebView hiển thị nội dung với giao diện tối tác giả nội dung đã xác định. Nếu được tác giả nội dung cho phép, WebView sẽ hiển thị nội dung đó bằng giao diện tối được tạo bằng thuật toán.

Định kiểu theo tác giả nội dung

của một ứng dụng Thuộc tính isLightTheme cho biết giao diện của ứng dụng là sáng hay tối. WebView luôn đặt prefers-color-scheme theo isLightTheme. Nếu isLightThemetrue hoặc không được chỉ định, thì prefers-color-scheme sẽ là light; nếu không thì dark.

Điều này có nghĩa là nếu nội dung trên web sử dụng prefers-color-scheme và nội dung tác giả cho phép, giao diện sáng hoặc tối do tác giả nội dung xác định luôn được tự động áp dụng cho nội dung trên web để phù hợp với giao diện của ứng dụng.

Làm tối bằng thuật toán

Để xử lý các trường hợp mà nội dung trên web không sử dụng prefers-color-scheme! ứng dụng của bạn có thể cho phép WebView áp dụng tối ưu hoá theo thuật toán khi cần thiết cho nội dung web mà nó hiển thị.

Nếu ứng dụng của bạn đang sử dụng cấp ứng dụng Buộc chế độ tối thành thuật toán áp dụng giao diện tối cho ứng dụng, hãy xem phần sau đây mô tả cách cho phép thuật toán làm tối nội dung trên web bằng tính năng Buộc chế độ tối.

Nếu ứng dụng của bạn không dùng tính năng Buộc chế độ tối, thì ứng dụng sẽ chỉ định thời điểm cho phép Chế độ làm tối dựa trên thuật toán trong WebView phụ thuộc vào cấp độ API mục tiêu. Hãy xem các phần sau về ứng dụng nhắm đến Android 13 trở lênứng dụng nhắm đến Android 12 trở xuống để biết thông tin chi tiết.

Cho phép chế độ làm tối dựa trên thuật toán cho nội dung trên web bằng tính năng Buộc chế độ tối

Nếu ứng dụng của bạn đang sử dụng cấp ứng dụng Buộc chế độ tối, WebView sẽ áp dụng làm tối nội dung trên web bằng thuật toán nếu các điều kiện sau được đáp ứng:

  • WebView và các thành phần mẹ cho phép tính năng Buộc chế độ tối.
  • Chủ đề hoạt động hiện tại được đánh dấu là sáng bằng Đã đặt isLightTheme thành true.
  • Tác giả nội dung web không tắt chế độ làm tối một cách rõ ràng.
  • Đối với ứng dụng nhắm đến Android 13 (API cấp 33) trở lên, nội dung trên web không sử dụng prefers-color-scheme.
  • Đối với ứng dụng nhắm đến Android 12 (API cấp 32) trở xuống: Ứng dụng đã đặt Cài đặt forceDarkMode của WebView đến FORCE_DARK_AUTO và đã thiết lập chiến lược Buộc tối DARK_STRATEGY_USER_AGENT_DARKENING_ONLY.

WebView và tất cả thành phần mẹ có thể cho phép dùng tính năng buộc làm tối View.setForceDarkAllowed(). Giá trị mặc định được lấy từ thuộc tính setForceDarkAllowed() của Giao diện Android, cũng phải được đặt thành true.

Buộc sử dụng Chế độ tối được cung cấp chủ yếu cho khả năng tương thích ngược trong các ứng dụng không cung cấp giao diện tối riêng. Nếu ứng dụng của bạn sử dụng tính năng Buộc chế độ tối, bạn nên thêm tính năng hỗ trợ cho giao diện tối.

Cho phép làm tối theo thuật toán (ứng dụng nhắm đến Android 13 trở lên)

Đối với ứng dụng không dùng tính năng Buộc chế độ tối ở cấp ứng dụng và nhắm đến Android 13 (cấp độ API) 33) trở lên, hãy sử dụng AndroidX setAlgorithmicDarkeningAllowed() và chuyển vào true để chỉ định rằng một WebView phải cho phép thuật toán tối. Phương thức này có khả năng tương thích ngược với các phiên bản Android trước đó của Google.

Sau đó, WebView sẽ áp dụng chế độ làm tối theo thuật toán nếu đáp ứng các điều kiện sau:

  • Nội dung trên web không sử dụng prefers-color-scheme.
  • Tác giả nội dung web không tắt chế độ làm tối một cách rõ ràng.

Cho phép làm tối theo thuật toán (ứng dụng nhắm đến Android 12 trở xuống)

Đối với ứng dụng không dùng tính năng Buộc chế độ tối ở cấp ứng dụng và nhắm đến Android 12 (cấp độ API) 32) trở xuống, hãy sử dụng FORCE_DARK_ON để cho phép làm tối theo thuật toán.

Sử dụng FORCE_DARK_ON cùng với FORCE_DARK_OFF nếu ứng dụng của bạn cung cấp phương thức riêng để chuyển đổi giữa giao diện sáng và tối, chẳng hạn như một phần tử có thể bật/tắt trong giao diện người dùng hoặc lựa chọn tự động dựa trên thời gian.

Để kiểm tra xem tính năng này có được hỗ trợ hay không, hãy thêm các dòng mã sau bất cứ nơi nào bạn định cấu hình đối tượng WebView, chẳng hạn như trong Activity.onCreate:

Kotlin

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

Java

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

Nếu ứng dụng của bạn dựa vào việc phát hiện các thay đổi đối với lựa chọn ưu tiên về hệ thống, thì ứng dụng đó lắng nghe rõ ràng các thay đổi về giao diện và áp dụng những thay đổi đó cho WebView bằng Trạng thái FORCE_DARK_ONFORCE_DARK_OFF.

Đoạn mã sau đây cho biết cách thay đổi định dạng giao diện:

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

Tuỳ chỉnh cách xử lý giao diện tối

Bạn cũng có thể sử dụng APIForceDarkStrategy trong AndroidX để kiểm soát cách áp dụng chế độ làm tối cho một WebView nhất định. API này là chỉ áp dụng nếu tính năng buộc tối được đặt thành FORCE_DARK_ON hoặc FORCE_DARK_AUTO.

Khi sử dụng API, ứng dụng của bạn có thể sử dụng chế độ làm tối giao diện web hoặc tác nhân người dùng làm tối:

  • Làm tối giao diện web: Các nhà phát triển web có thể áp dụng tính năng này @media (prefers-color-scheme: dark) để kiểm soát giao diện của trang web trong chế độ tối. WebView hiển thị nội dung theo các chế độ cài đặt này. Để biết thêm thông tin về giao diện web tối đi, hãy xem thông số kỹ thuật.
  • Làm tối tác nhân người dùng: WebView tự động đảo ngược màu của trang web . Nếu bạn sử dụng chế độ làm tối tác nhân người dùng, Truy vấn @media (prefers-color-scheme: dark) có giá trị false.

Để chọn giữa hai chiến lược, hãy sử dụng API sau:

Kotlin

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

Java

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

Các chiến lược được hỗ trợ bao gồm:

  • DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING: Đây là lựa chọn mặc định. Mặc dù hầu hết các trình duyệt đều xử lý Thẻ <meta name="color-scheme" content="dark light"> là không bắt buộc, Android Chế độ mặc định của WebView yêu cầu thẻ meta phải tuân thủ prefers-color-scheme truy vấn đa phương tiện. Bạn có thể sử dụng WebView với DARK_STRATEGY_WEB_THEME_DARKENING_ONLY , trong trường hợp đó, WebView luôn áp dụng các truy vấn phương tiện ngay cả khi thẻ đã bỏ qua.

    Tuy nhiên, nhà phát triển web nên thêm <meta name="color-scheme" content="dark light"> gắn thẻ vào trang web của họ để đảm bảo rằng nội dung hiển thị chính xác trong WebView với cấu hình mặc định.

  • DARK_STRATEGY_USER_AGENT_DARKENING_ONLY: Có tên "làm tối tác nhân người dùng", WebView bỏ qua mọi hoạt động làm tối trang web và áp dụng chế độ làm tối tự động.

Nếu ứng dụng của bạn hiển thị nội dung web của bên thứ nhất mà bạn đã tuỳ chỉnh bằng prefers-color-scheme truy vấn phương tiện, bạn nên DARK_STRATEGY_WEB_THEME_DARKENING_ONLY để đảm bảo WebView sử dụng giao diện tuỳ chỉnh.

Để xem ví dụ về cách áp dụng giao diện tối, hãy xem Bản minh hoạ WebView trên GitHub