แอปของคุณทำงานได้ดีในโทรศัพท์ที่อยู่ในแนวนอน คุณจึงจำกัด แอปให้แสดงในแนวตั้งเท่านั้น แต่คุณเห็นโอกาสที่จะทำสิ่งต่างๆ ได้มากขึ้นบนหน้าจอขนาดใหญ่ใน แนวนอนหรืออุปกรณ์แบบพับได้ที่กางออก
คุณจะจำกัดแอปให้แสดงในแนวตั้งบนหน้าจอด้านนอกของอุปกรณ์พับได้ แต่เปิดใช้แนวนอนบนหน้าจอด้านในได้อย่างไร
คำแนะนำนี้เป็นมาตรการชั่วคราวจนกว่าคุณจะปรับปรุงแอปให้รองรับการกำหนดค่าอุปกรณ์ทั้งหมดได้อย่างเต็มรูปแบบ
ผลลัพธ์
แอปจะยังคงอยู่ในแนวตั้งบนหน้าจอขนาดเล็กไม่ว่าจะหมุนอุปกรณ์อย่างไรก็ตาม ในหน้าจอขนาดใหญ่ แอปจะรองรับการวางแนวแนวนอนและแนวตั้ง
ความเข้ากันได้ของเวอร์ชัน
การติดตั้งใช้งานนี้ใช้ได้กับ 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 ในวงกว้าง