แอปของคุณทำงานได้ดีในโทรศัพท์ในแนวตั้ง คุณจึงจำกัดแอปให้แสดงในแนวตั้งเท่านั้น แต่คุณเห็นโอกาสที่จะทําสิ่งต่างๆ ได้มากขึ้นบนหน้าจอขนาดใหญ่ในแนวนอน
คุณจะทำอย่างไรได้บ้างหากต้องการจำกัดแอปให้แสดงในแนวตั้งบนหน้าจอขนาดเล็ก แต่เปิดใช้แนวนอนบนหน้าจอขนาดใหญ่
คู่มือนี้เป็นมาตรการชั่วคราวจนกว่าคุณจะปรับปรุงแอปให้รองรับการกำหนดค่าอุปกรณ์ทั้งหมดได้
จัดการการวางแนวของแอป
หากต้องการเปิดใช้การวางแนวแนวนอนบนหน้าจอขนาดใหญ่ ให้ตั้งค่าไฟล์ Manifest ของแอปให้จัดการการเปลี่ยนแปลงการวางแนวโดยค่าเริ่มต้น กำหนดขนาดหน้าต่างแอปขณะรันไทม์ หากหน้าต่างแอปมีขนาดเล็ก ให้จำกัดการวางแนวของแอปโดยการลบล้างการตั้งค่าการวางแนวไฟล์ Manifest
1. ระบุการตั้งค่าการวางแนวในไฟล์ Manifest ของแอป
คุณสามารถหลีกเลี่ยงการประกาศองค์ประกอบ screenOrientation
ของไฟล์ Manifest ของแอป (ซึ่งในกรณีนี้การวางแนวจะเป็น unspecified
โดยค่าเริ่มต้น) หรือตั้งค่าการวางแนวหน้าจอเป็น fullUser
หากผู้ใช้ไม่ได้ล็อกการหมุนตามเซ็นเซอร์ไว้ แอปจะรองรับการวางแนวอุปกรณ์ทุกรูปแบบ
<activity
android:name=".MyActivity"
android:screenOrientation="fullUser">
ความแตกต่างระหว่าง unspecified
กับ fullUser
นั้นเล็กน้อยแต่สำคัญ หากคุณไม่ประกาศค่า screenOrientation
ระบบจะเลือกการวางแนว และนโยบายที่ระบบใช้เพื่อกำหนดการวางแนวอาจแตกต่างกันไปในแต่ละอุปกรณ์ ในทางกลับกัน การระบุ fullUser
จะตรงกับลักษณะการทำงานที่ผู้ใช้กำหนดไว้สำหรับอุปกรณ์มากกว่า หากผู้ใช้ล็อกการหมุนตามเซ็นเซอร์ไว้ แอปจะเป็นไปตามค่ากำหนดของผู้ใช้ มิเช่นนั้น ระบบจะอนุญาตให้ใช้การวางแนวหน้าจอได้ 4 แบบ (แนวตั้ง แนวนอน แนวตั้งกลับด้าน หรือแนวนอนกลับด้าน) โปรดดู 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
เมตริกกรอบเวลาสามารถเปรียบเทียบกับคลาสขนาดหน้าต่างเพื่อตัดสินใจว่าจะจำกัดการวางแนวเมื่อใด
Window Size Classes จะระบุจุดแบ่งระหว่างหน้าจอขนาดเล็กและขนาดใหญ่
ใช้จุดตัด WindowWidthSizeClass#COMPACT
และ WindowHeightSizeClass#COMPACT
เพื่อกำหนดขนาดหน้าจอ
Kotlin
/** 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 = WindowSizeClass.compute(width/density, height/density) return windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.COMPACT || windowSizeClass.windowHeightSizeClass == WindowHeightSizeClass.COMPACT }
Java
/** Determines whether the device has a compact screen. **/ private boolean compactScreen() { WindowMetrics metrics = WindowMetricsCalculator.getOrCreate().computeMaximumWindowMetrics(this); int width = metrics.getBounds().width(); int height = metrics.getBounds().height(); float density = getResources().getDisplayMetrics().density; WindowSizeClass windowSizeClass = WindowSizeClass.compute(width/density, height/density); return windowSizeClass.getWindowWidthSizeClass() == WindowWidthSizeClass.COMPACT || windowSizeClass.getWindowHeightSizeClass() == WindowHeightSizeClass.COMPACT; }
- หมายเหตุ:
- ตัวอย่างนี้ใช้งานเป็นเมธอดของกิจกรรม ดังนั้นระบบจะยกเลิกการอ้างอิงกิจกรรมเป็น
this
ในอาร์กิวเมนต์ของcomputeMaximumWindowMetrics()
- ระบบจะใช้เมธอด
computeMaximumWindowMetrics()
แทนcomputeCurrentWindowMetrics()
เนื่องจากแอปสามารถเปิดได้ในโหมดหลายหน้าต่าง ซึ่งจะไม่สนใจการตั้งค่าการวางแนวหน้าจอ การกำหนดขนาดหน้าต่างแอปและการลบล้างการตั้งค่าการวางแนวนั้นไม่มีประโยชน์ เว้นแต่หน้าต่างแอปจะเป็นหน้าจอทั้งหน้าจอของอุปกรณ์
ดูวิธีการประกาศการพึ่งพาเพื่อให้เมธอด computeMaximumWindowMetrics()
พร้อมใช้งานในแอปได้ที่ WindowManager
3. ลบล้างการตั้งค่าไฟล์ Manifest ของแอป
เมื่อคุณพิจารณาแล้วว่าอุปกรณ์มีขนาดหน้าจอกะทัดรัด คุณสามารถเรียกใช้ Activity#setRequestedOrientation()
เพื่อลบล้างการตั้งค่า screenOrientation
ของไฟล์ Manifest ดังนี้
Kotlin
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 } }) }
Java
@Override protected void onCreate(Bundle savedInstance) { super.onCreate(savedInstanceState); if (compactScreen()) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } else { setRequestedOrientation(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. ViewGroup container = 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(new View(this) { @Override protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); if (compactScreen()) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } else { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_USER); } } }); }
การเพิ่มตรรกะลงในเมธอด onCreate()
และ View.onConfigurationChanged()
จะช่วยให้คุณได้รับเมตริกหน้าต่างสูงสุดและลบล้างการตั้งค่าการวางแนวทุกครั้งที่มีการปรับขนาดหรือย้ายกิจกรรมระหว่างจอแสดงผล เช่น หลังจากหมุนอุปกรณ์หรือเมื่อพับหรือกางอุปกรณ์แบบพับได้
ดูข้อมูลเพิ่มเติมเกี่ยวกับเวลาที่การเปลี่ยนแปลงการกําหนดค่าเกิดขึ้นและเวลาที่ทําให้สร้างกิจกรรมอีกครั้งได้ที่จัดการการเปลี่ยนแปลงการกําหนดค่า
ข้อมูลสำคัญ
screenOrientation
: การตั้งค่าไฟล์ Manifest ของแอปที่ช่วยให้คุณระบุวิธีตอบสนองของแอปต่อการเปลี่ยนแปลงการวางแนวของอุปกรณ์ได้- Jetpack WindowManager: ชุดไลบรารีที่ช่วยให้คุณกำหนดขนาดและสัดส่วนภาพของหน้าต่างแอปได้ ใช้งานร่วมกับ API ระดับ 14 ย้อนหลังได้
Activity#setRequestedOrientation()
: วิธีการเปลี่ยนการวางแนวของแอปขณะรันไทม์
ผลลัพธ์
ตอนนี้แอปของคุณควรอยู่ในแนวตั้งบนหน้าจอขนาดเล็ก ไม่ว่าจะหมุนอุปกรณ์อย่างไรก็ตาม บนหน้าจอขนาดใหญ่ แอปควรรองรับการวางแนวแนวนอนและแนวตั้ง
คอลเล็กชันที่มีคู่มือนี้
คู่มือนี้เป็นส่วนหนึ่งของคอลเล็กชันคู่มือฉบับย่อที่มีการดูแลจัดการซึ่งครอบคลุมเป้าหมายการพัฒนา Android ที่กว้างขึ้น ดังนี้
![](https://developer.android.com/static/images/quick-guides/collection-illustration.png?hl=th)