จำกัดการวางแนวแอปในโทรศัพท์และหน้าจอด้านนอกของอุปกรณ์แบบพับได้ แต่ไม่จำกัดในจอแสดงผลขนาดใหญ่

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

คุณจะจำกัดแอปให้แสดงในแนวตั้งบนหน้าจอด้านนอกของอุปกรณ์พับได้ แต่เปิดใช้แนวนอนบนหน้าจอด้านในได้อย่างไร

คำแนะนำนี้เป็นมาตรการชั่วคราวจนกว่าคุณจะปรับปรุงแอปให้รองรับการกำหนดค่าอุปกรณ์ทั้งหมดได้อย่างเต็มรูปแบบ

ผลลัพธ์

แอปจะยังคงอยู่ในแนวตั้งบนหน้าจอขนาดเล็กไม่ว่าจะหมุนอุปกรณ์อย่างไรก็ตาม ในหน้าจอขนาดใหญ่ แอปจะรองรับการวางแนวแนวนอนและแนวตั้ง

ความเข้ากันได้ของเวอร์ชัน

การติดตั้งใช้งานนี้ใช้ได้กับ API ทุกระดับ

การขึ้นต่อกัน

Kotlin

implementation("androidx.window:window:1.5.1")
implementation("androidx.window:window-core:1.5.1")

Groovy

implementation "androidx.window:window:1.5.1"
implementation "androidx.window:window-core:1.5.1"

จัดการการวางแนวของแอป

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

1. ระบุการตั้งค่าการวางแนวในไฟล์ Manifest ของแอป

คุณสามารถหลีกเลี่ยงการประกาศองค์ประกอบ screenOrientation ของไฟล์ Manifest ของแอป (ในกรณีนี้ การวางแนวจะเป็นค่าเริ่มต้นเป็น unspecified) หรือตั้งค่าการวางแนวหน้าจอเป็น fullUser หากผู้ใช้ไม่ได้ล็อกการหมุนตามเซ็นเซอร์ แอปของคุณจะรองรับการวางแนวอุปกรณ์ทั้งหมด

<activity
    android:name=".MyActivity"
    android:screenOrientation="fullUser">

ความแตกต่างระหว่าง unspecified กับ fullUser อาจดูเล็กน้อยแต่มีความสำคัญ หากคุณไม่ประกาศค่า screenOrientation ระบบจะเลือกการวางแนว และนโยบายที่ระบบใช้เพื่อกำหนดการวางแนวอาจแตกต่างกันไปในแต่ละอุปกรณ์

ในทางกลับกัน การระบุ fullUser จะตรงกับลักษณะการทำงานที่ผู้ใช้กำหนดไว้สำหรับอุปกรณ์มากกว่า กล่าวคือ หากผู้ใช้ล็อกการหมุนตามเซ็นเซอร์ แอปจะทำตามค่ากำหนดของผู้ใช้ ไม่เช่นนั้น ระบบจะอนุญาตการวางแนวหน้าจอที่เป็นไปได้ทั้ง 4 แบบ (แนวตั้ง แนวนอน แนวตั้งกลับ หรือแนวนอนกลับ)

นอกจากนี้ คุณยังใช้ nosensor เพื่อกำหนดการวางแนวโดยไม่ต้องคำนึงถึงข้อมูลเซ็นเซอร์ได้ แต่โค้ดต่อไปนี้จะทำงานในลักษณะเดียวกัน ดู screenOrientation

2. กำหนดขนาดหน้าจอ

เมื่อตั้งค่าไฟล์ Manifest ให้รองรับการวางแนวทั้งหมดที่ผู้ใช้ได้รับอนุญาตแล้ว คุณจะ ระบุการวางแนวแอปแบบเป็นโปรแกรมตามขนาดหน้าจอได้

เพิ่มไลบรารี Jetpack WindowManager ลงในไฟล์ build.gradle หรือ build.gradle.kts ของโมดูล

Kotlin

implementation("androidx.window:window:version")
implementation("androidx.window:window-core:version")

Groovy

implementation 'androidx.window:window:version'
implementation 'androidx.window:window-core:version'

ใช้เมธอด Jetpack WindowManager WindowMetricsCalculator#computeMaximumWindowMetrics() เพื่อรับ ขนาดหน้าจออุปกรณ์เป็นออบเจ็กต์ WindowMetrics คุณสามารถ เปรียบเทียบเมตริกหน้าต่างกับคลาสขนาดหน้าต่างเพื่อตัดสินใจว่าจะจำกัดการวางแนวเมื่อใด

คลาสขนาดหน้าต่างระบุเบรกพอยต์ระหว่างหน้าจอขนาดเล็กและขนาดใหญ่

ใช้จุดพัก WindowSizeClass#minWidthDp และ WindowSizeClass#minHeightDp เพื่อกำหนดขนาดหน้าจอ

/** Determines whether the device has a compact screen. **/
fun compactScreen() : Boolean {
    val metrics = WindowMetricsCalculator.getOrCreate().computeMaximumWindowMetrics(this)
    val width = metrics.bounds.width()
    val height = metrics.bounds.height()
    val density = resources.displayMetrics.density
    val windowSizeClass =
        BREAKPOINTS_V1.computeWindowSizeClass(width / density, height / density)
    return windowSizeClass.minWidthDp == 0
}
    หมายเหตุ:
  • ตัวอย่างจะได้รับการติดตั้งใช้งานเป็นเมธอดของกิจกรรม ดังนั้นระบบจึงยกเลิกการอ้างอิงกิจกรรมเป็น this ในอาร์กิวเมนต์ของ computeMaximumWindowMetrics()
  • เราใช้วิธี computeMaximumWindowMetrics() แทน computeCurrentWindowMetrics() เนื่องจากแอปสามารถเปิดในโหมดหลายหน้าต่างได้ ซึ่งจะไม่สนใจการตั้งค่าการวางแนวหน้าจอ ไม่มีเหตุผลที่จะกำหนดขนาดหน้าต่างแอปและลบล้างการตั้งค่าการวางแนว เว้นแต่หน้าต่างแอปจะเป็นทั้งหน้าจอของอุปกรณ์

ดูWindowManager เพื่อดูวิธีการประกาศการอ้างอิงเพื่อให้เมธอด computeMaximumWindowMetrics() พร้อมใช้งานในแอป

3. ลบล้างการตั้งค่าไฟล์ Manifest ของแอป

เมื่อพิจารณาแล้วว่าอุปกรณ์มีขนาดหน้าจอแบบกะทัดรัด คุณสามารถเรียกใช้ Activity#setRequestedOrientation() เพื่อลบล้างการตั้งค่า screenOrientation ของไฟล์ Manifest ได้

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    requestedOrientation = if (compactScreen())
        ActivityInfo.SCREEN_ORIENTATION_PORTRAIT else
        ActivityInfo.SCREEN_ORIENTATION_FULL_USER
    ...
    // Replace with a known container that you can safely add a
    // view to where the view won't affect the layout and the view
    // won't be replaced.
    val container: ViewGroup = binding.container

    // Add a utility view to the container to hook into
    // View.onConfigurationChanged. This is required for all
    // activities, even those that don't handle configuration
    // changes. You can't use Activity.onConfigurationChanged,
    // since there are situations where that won't be called when
    // the configuration changes. View.onConfigurationChanged is
    // called in those scenarios.
    container.addView(object : View(this) {
        override fun onConfigurationChanged(newConfig: Configuration?) {
            super.onConfigurationChanged(newConfig)
            requestedOrientation = if (compactScreen())
                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT else
                ActivityInfo.SCREEN_ORIENTATION_FULL_USER
        }
    })
}

การเพิ่มตรรกะลงในเมธอด onCreate() และ View.onConfigurationChanged() จะช่วยให้คุณได้รับเมตริกหน้าต่างสูงสุดและลบล้างการตั้งค่า การวางแนวได้ทุกเมื่อที่กิจกรรมมีการปรับขนาดหรือย้ายระหว่างจอแสดงผล เช่น หลังจากหมุนอุปกรณ์ หรือเมื่อพับหรือกางอุปกรณ์พับได้ ดูข้อมูลเพิ่มเติมเกี่ยวกับเวลาที่การเปลี่ยนแปลงการกำหนดค่าเกิดขึ้นและเวลาที่การเปลี่ยนแปลงดังกล่าวทำให้เกิดการสร้างกิจกรรมใหม่ได้ที่จัดการการเปลี่ยนแปลงการกำหนดค่า

หากใช้ Jetpack Compose คุณสามารถใช้compactScreen()ฟังก์ชัน เดียวกันใน Composable รูทของแอปเพื่อให้ได้ผลลัพธ์เดียวกัน

ข้อมูลสำคัญ

  • screenOrientation: การตั้งค่าไฟล์ Manifest ของแอปที่ช่วยให้คุณระบุได้ วิธีที่แอปตอบสนองต่อการเปลี่ยนแปลงการวางแนวอุปกรณ์
  • Jetpack WindowManager: ชุดไลบรารีที่ช่วยให้คุณกำหนดขนาดและสัดส่วนของหน้าต่างแอปได้ โดยสามารถใช้งานร่วมกับ API ระดับ 14 ได้
  • Activity#setRequestedOrientation(): วิธีที่คุณสามารถเปลี่ยน การวางแนวแอปในขณะรันไทม์

คอลเล็กชันที่มีคำแนะนำนี้

คู่มือนี้เป็นส่วนหนึ่งของคอลเล็กชันคู่มือฉบับย่อที่คัดสรรมาแล้ว ซึ่งครอบคลุมเป้าหมายการพัฒนา Android ในวงกว้าง

เปิดใช้แอปให้รองรับประสบการณ์ของผู้ใช้ที่ได้รับการเพิ่มประสิทธิภาพในแท็บเล็ต อุปกรณ์พับได้ และอุปกรณ์ ChromeOS

มีคำถามหรือความคิดเห็น

ไปที่หน้าคำถามที่พบบ่อยเพื่อดูคำแนะนำแบบรวดเร็ว หรือติดต่อเราเพื่อบอกความคิดเห็นของคุณ