ปรับเนื้อหาเว็บให้มืดใน 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 ไม่เช่นนั้นจะเป็น dark

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

การทำให้มืดลงโดยอัลกอริทึม

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

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

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

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

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

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

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

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

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

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

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

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

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

สำหรับแอปที่ไม่ได้ใช้บังคับใช้ธีมมืดระดับแอปและกำหนดเป้าหมายเป็น 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 ในไลบรารี Jetpack เพื่อควบคุมวิธีใช้การทำให้มืดลงกับ WebView ที่ระบุได้ด้วย API นี้ใช้ได้เฉพาะในกรณีที่ตั้งค่า Force Dark เป็น FORCE_DARK_ON หรือ FORCE_DARK_AUTO

แอปสามารถใช้การทำให้ธีมเว็บมืดลงหรือการทำให้ User Agent มืดลงโดยใช้ API ดังนี้

  • การทำให้ธีมเว็บมืดลง: นักพัฒนาเว็บอาจใช้ @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's กำหนดให้แท็ก Meta ต้องปฏิบัติตามการค้นหาสื่อ 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: เรียกว่า "การทำให้ User Agent มืดลง" WebView จะไม่สนใจการทำให้หน้าเว็บมืดลงและใช้การทำให้มืดลงโดยอัตโนมัติ

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

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