ปรับเนื้อหาเว็บให้มืดใน WebView

ใน Android 10 ขึ้นไป แอปจะรองรับธีมมืดและเปลี่ยนธีมแอประหว่างธีมสว่างและธีมมืดโดยอัตโนมัติตามธีมของระบบ เนื้อหาเว็บใน WebView สามารถใช้การจัดรูปแบบแบบสว่าง แบบมืด หรือแบบเริ่มต้นเพื่อให้เข้ากับธีมปัจจุบันของแอป

ลักษณะการทํางานของ WebView จะทํางานร่วมกับมาตรฐานเว็บของ prefers-color-scheme และ color-scheme หากคุณเป็นผู้เขียนเนื้อหาเว็บที่ต้องการให้แอปแสดงใน WebView คุณควรกำหนดธีมสีเข้มสำหรับเว็บไซต์และติดตั้งใช้งาน prefers-color-scheme เพื่อให้ WebView จับคู่ธีมของเนื้อหาเว็บกับธีมของแอปได้ (หากเป็นไปได้)

ตารางต่อไปนี้อธิบายวิธีที่ WebView แสดงผลเนื้อหาเว็บในแอป โดยขึ้นอยู่กับการจัดรูปแบบของเนื้อหาเว็บและเงื่อนไขของแอป

เงื่อนไขของแอป เนื้อหาเว็บที่ใช้ prefers-color-scheme เนื้อหาเว็บที่ไม่ได้ใช้ prefers-color-scheme
แอปกำลังใช้ธีมสว่างที่ตั้งค่า isLightTheme เป็น true หรือไม่ได้ตั้งค่า WebView จะแสดงผลเนื้อหาด้วยธีมแสงที่ผู้เขียนเนื้อหากำหนดไว้ WebView จะแสดงผลเนื้อหาด้วยการจัดรูปแบบเริ่มต้นที่ผู้เขียนเนื้อหากำหนด
แอปใช้บังคับใช้ธีมมืดเพื่อใช้ธีมมืดกับแอปตามอัลกอริทึม WebView จะแสดงผลเนื้อหาด้วยธีมสีเข้มที่ผู้เขียนเนื้อหากำหนดไว้ หากผู้เขียนเนื้อหาอนุญาต WebView จะแสดงผลเนื้อหาด้วยธีมมืดที่สร้างขึ้นโดยใช้อัลกอริทึม
แอปใช้ธีมมืดโดยตั้งค่า isLightTheme เป็น false และแอปไม่อนุญาตการปรับสีเข้มตามอัลกอริทึมสำหรับ WebView WebView จะแสดงผลเนื้อหาด้วยธีมสีเข้มที่ผู้เขียนเนื้อหากำหนดไว้ WebView จะแสดงผลเนื้อหาด้วยการจัดรูปแบบเริ่มต้นที่ผู้เขียนเนื้อหากำหนด
แอปใช้ธีมมืดที่ตั้งค่า isLightTheme เป็น false และแอปอนุญาต การปรับให้มืดลงแบบอัลกอริทึมสำหรับ WebView WebView จะแสดงผลเนื้อหาด้วยธีมสีเข้มที่ผู้เขียนเนื้อหากำหนดไว้ หากผู้เขียนเนื้อหาอนุญาต WebView จะแสดงผลเนื้อหาด้วยธีมสีเข้มที่สร้างขึ้นโดยใช้อัลกอริทึม

การจัดรูปแบบของผู้เขียนเนื้อหา

แอตทริบิวต์ isLightTheme ของแอปจะบ่งบอกว่าธีมของแอปเป็นธีมสว่างหรือธีมมืด WebView จะตั้งค่า prefers-color-scheme ตาม isLightTheme เสมอ หาก isLightTheme เป็น true หรือไม่ได้ระบุ prefers-color-scheme จะเป็น light มิเช่นนั้น prefers-color-scheme จะเป็น dark

ซึ่งหมายความว่าหากเนื้อหาเว็บใช้ prefers-color-scheme และผู้เขียนเนื้อหาอนุญาต ระบบจะใช้ธีมแบบสว่างหรือแบบมืดที่ผู้เขียนเนื้อหากำหนดไว้กับเนื้อหาเว็บโดยอัตโนมัติเสมอเพื่อให้เข้ากับธีมของแอป

การปรับให้มืดลงแบบอัลกอริทึม

เพื่อให้ครอบคลุมกรณีที่เนื้อหาเว็บไม่ได้ใช้ prefers-color-scheme แอปจะอนุญาตให้ใช้ WebView เพื่อใช้ธีมมืดตามอัลกอริทึมกับเนื้อหาเว็บที่แสดงผลได้ (หากจำเป็น)

หากแอปใช้บังคับใช้โหมดมืดระดับแอปเพื่อใช้ธีมมืดกับแอปตามอัลกอริทึม โปรดดูส่วนต่อไปนี้ซึ่งอธิบายวิธีอนุญาตการปรับเนื้อหาเว็บเป็นสีเข้มตามอัลกอริทึมด้วยฟีเจอร์บังคับใช้โหมดมืด

หากแอปไม่ได้ใช้โหมดบังคับใช้โหมดมืด วิธีที่แอประบุเวลาที่จะอนุญาตให้มีการปรับความมืดตามอัลกอริทึมใน WebView จะขึ้นอยู่กับระดับ API เป้าหมายของแอป ดูรายละเอียดเกี่ยวกับแอปที่กำหนดเป้าหมายเป็น Android 13 ขึ้นไป และแอปที่กำหนดเป้าหมายเป็น Android 12 หรือต่ำกว่าได้ที่ส่วนต่อไปนี้

อนุญาตการปรับให้มืดตามอัลกอริทึมสำหรับเนื้อหาเว็บโดยใช้ฟีเจอร์บังคับใช้สีเข้ม

หากแอปใช้บังคับใช้โหมดมืดระดับแอป WebView จะใช้อัลกอริทึมปรับความมืดกับเนื้อหาเว็บหากเป็นไปตามเงื่อนไขต่อไปนี้

  • WebView และองค์ประกอบหลักของ WebView อนุญาตให้ใช้โหมดมืด
  • ธีมกิจกรรมปัจจุบันมีการทำเครื่องหมายเป็น "สว่าง" โดยตั้งค่า isLightTheme เป็น true
  • ผู้เขียนเนื้อหาเว็บไม่ได้ปิดใช้การทำให้เข้มขึ้นอย่างชัดเจน
  • สําหรับแอปที่กําหนดเป้าหมายเป็น Android 13 (API ระดับ 33) ขึ้นไป เนื้อหาเว็บจะไม่ใช้ prefers-color-scheme
  • สําหรับแอปที่กําหนดเป้าหมายเป็น Android 12 (API ระดับ 32) หรือต่ำกว่า: แอปได้ตั้งค่าการตั้งค่า forceDarkMode ของ WebView เป็น FORCE_DARK_AUTO และตั้งค่ากลยุทธ์ "บังคับใช้โหมดมืด" เป็น DARK_STRATEGY_USER_AGENT_DARKENING_ONLY

WebView และระดับบนสุดทั้งหมดอนุญาตให้บังคับใช้โหมดมืดได้โดยใช้ View.setForceDarkAllowed() ค่าเริ่มต้นจะมาจากแอตทริบิวต์ setForceDarkAllowed() ของธีม Android ซึ่งต้องตั้งค่าเป็น true ด้วย

โหมดบังคับใช้โหมดมืดมีไว้เพื่อการทำงานร่วมกันแบบย้อนหลังเป็นหลักในแอปที่ไม่ได้มีธีมมืดของตัวเอง หากแอปใช้ "บังคับใช้ธีมมืด" เราขอแนะนำให้เพิ่มการรองรับธีมมืด

อนุญาตการทำให้มืดลงตามอัลกอริทึม (แอปที่กำหนดเป้าหมายเป็น Android 13 ขึ้นไป)

สําหรับแอปที่ไม่ได้ใช้โหมดบังคับใช้โหมดมืดระดับแอปและกำหนดเป้าหมายเป็น Android 13 (API ระดับ 33) ขึ้นไป ให้ใช้เมธอด AndroidX setAlgorithmicDarkeningAllowed() และส่ง true เพื่อระบุว่า WebView ควรอนุญาตให้ใช้อัลกอริทึมเปลี่ยนเป็นโหมดมืด วิธีนี้ใช้ได้กับ Android เวอร์ชันก่อนหน้า

จากนั้น WebView จะใช้การปรับให้มืดตามอัลกอริทึมหากเป็นไปตามเงื่อนไขต่อไปนี้

  • เนื้อหาเว็บไม่ได้ใช้ prefers-color-scheme
  • ผู้เขียนเนื้อหาเว็บไม่ได้ปิดใช้การทำให้เข้มขึ้นอย่างชัดเจน

อนุญาตการทำให้เข้มขึ้นตามอัลกอริทึม (แอปที่กำหนดเป้าหมายเป็น Android 12 หรือต่ำกว่า)

สำหรับแอปที่ไม่ได้ใช้ Force Dark ระดับแอปและกำหนดเป้าหมายเป็น Android 12 (API ระดับ 32) หรือต่ำกว่า ให้ใช้ FORCE_DARK_ON เพื่ออนุญาตการปรับให้มืดตามอัลกอริทึม

ใช้ FORCE_DARK_ON ร่วมกับ FORCE_DARK_OFF หากแอปของคุณมีวิธีการเฉพาะในการสลับระหว่างธีมสว่างและธีมมืด เช่น องค์ประกอบที่สลับได้ใน UI หรือการเลือกตามเวลาอัตโนมัติ

หากต้องการตรวจสอบว่าระบบรองรับฟีเจอร์นี้หรือไม่ ให้เพิ่มบรรทัดโค้ดต่อไปนี้ทุกครั้งที่กำหนดค่าออบเจ็กต์ WebView เช่น ใน Activity.onCreate

Kotlin

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

Java

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

หากแอปต้องใช้การตรวจหาการเปลี่ยนแปลงค่ากำหนดของระบบ แอปควรคอยฟังการเปลี่ยนแปลงธีมอย่างชัดแจ้งและนำไปใช้กับ WebView ที่มีสถานะ FORCE_DARK_ON และ FORCE_DARK_OFF

ข้อมูลโค้ดต่อไปนี้แสดงวิธีเปลี่ยนรูปแบบธีม

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

ปรับแต่งการจัดการธีมมืด

นอกจากนี้ คุณยังใช้ ForceDarkStrategy API ใน AndroidX เพื่อควบคุมวิธีทำให้ WebView มืดลงได้ด้วย API นี้จะใช้ได้เมื่อตั้งค่าบังคับใช้โหมดมืดเป็น FORCE_DARK_ON หรือ FORCE_DARK_AUTO เท่านั้น

เมื่อใช้ API นี้ แอปจะใช้ธีมมืดของเว็บหรือธีมมืดของ User Agent ได้ ดังนี้

  • การทำให้ธีมเว็บเข้มขึ้น: นักพัฒนาเว็บอาจใช้ @media (prefers-color-scheme: dark) เพื่อควบคุมลักษณะที่ปรากฏของหน้าเว็บในโหมดมืด WebView จะแสดงผลเนื้อหาตามการตั้งค่าเหล่านี้ ดูข้อมูลเพิ่มเติมเกี่ยวกับการทำให้ธีมเว็บเข้มขึ้นได้ในข้อกำหนด
  • การปรับแสง User Agent: WebView จะกลับสีของหน้าเว็บโดยอัตโนมัติ หากใช้การปรับให้มืดของ User Agent การค้นหา @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 จะใช้คำค้นหาสื่อเสมอแม้ว่าจะละเว้นแท็กก็ตาม

    อย่างไรก็ตาม เราขอแนะนำให้นักพัฒนาเว็บเพิ่มแท็ก <meta name="color-scheme" content="dark light"> ลงในเว็บไซต์เพื่อให้เนื้อหาแสดงผลอย่างถูกต้องใน WebView ด้วยการกำหนดค่าเริ่มต้น

  • DARK_STRATEGY_USER_AGENT_DARKENING_ONLY: WebView จะไม่สนใจการปรับให้หน้าเว็บมืดลงและใช้การปรับให้มืดโดยอัตโนมัติเนื่องจากเรียกว่า "การปรับแสง User Agent"

หากแอปแสดงเนื้อหาเว็บของบุคคลที่หนึ่งที่คุณปรับแต่งด้วยคำค้นหาสื่อ prefers-color-scheme เราขอแนะนำให้DARK_STRATEGY_WEB_THEME_DARKENING_ONLY ดูแลให้ WebView ใช้ธีมที่กำหนดเอง

ดูตัวอย่างการใช้ธีมมืดได้ที่ตัวอย่าง WebView ใน GitHub