คลาสขนาดหน้าต่างคือชุดเบรกพอยต์วิวพอร์ตที่กำหนดไว้ซึ่งช่วยให้คุณ ออกแบบ พัฒนา และทดสอบเลย์เอาต์ที่ปรับเปลี่ยนตามอุปกรณ์/เลย์เอาต์ที่ปรับเปลี่ยนได้ เบรกพอยต์จะปรับสมดุล ความเรียบง่ายของเลย์เอาต์กับความยืดหยุ่นในการเพิ่มประสิทธิภาพแอปสำหรับกรณีที่ไม่เหมือนใคร
คลาสขนาดหน้าต่างจะจัดหมวดหมู่พื้นที่แสดงผลที่แอปของคุณใช้ได้เป็น กะทัดรัด ปานกลาง ขยาย ใหญ่ หรือใหญ่พิเศษ ความกว้างและความสูงที่ใช้ได้จะได้รับการจัดประเภทแยกกัน ดังนั้นในทุกช่วงเวลา แอปจะมี Window Size Class อยู่ 2 รายการ ได้แก่ รายการหนึ่งสำหรับความกว้างและอีกรายการหนึ่งสำหรับความสูง โดยปกติแล้ว ความกว้างที่ใช้ได้จะมีความสำคัญมากกว่าความสูงที่ใช้ได้เนื่องจากการเลื่อนแนวตั้งมีอยู่ทุกหนทุกแห่ง ดังนั้นคลาสขนาดหน้าต่างความกว้างจึงน่าจะเกี่ยวข้องกับ UI ของแอปมากกว่า


ดังที่แสดงในรูปภาพ จุดพักช่วยให้คุณคิดถึงเลย์เอาต์ในแง่ของอุปกรณ์และการกำหนดค่าต่อไปได้ เบรกพอยต์แต่ละคลาสขนาด แสดงถึงกรณีส่วนใหญ่สำหรับสถานการณ์อุปกรณ์ทั่วไป ซึ่งอาจเป็นกรอบอ้างอิงที่มีประโยชน์ เมื่อคุณคิดถึงการออกแบบเลย์เอาต์ที่อิงตามเบรกพอยต์
คลาสขนาด | เบรกพอยท์ | การแสดงอุปกรณ์ |
---|---|---|
ความกว้างแบบกะทัดรัด | width < 600dp | 99.96% ของโทรศัพท์ในแนวตั้ง |
ความกว้างปานกลาง | 600dp ≤ ความกว้าง < 840dp | 93.73% ของแท็บเล็ตในโหมดแนวตั้ง
จอแสดงผลด้านในขนาดใหญ่ส่วนใหญ่ในโหมดแนวตั้ง |
ความกว้างที่ขยายออก | 840dp ≤ ความกว้าง < 1200dp | 97.22% ของแท็บเล็ตในแนวนอน
หน้าจอด้านในขนาดใหญ่ส่วนใหญ่ที่กางออกในแนวนอนจะมี ความกว้างที่ขยายออกอย่างน้อย |
ความกว้างมาก | 1200dp ≤ ความกว้าง < 1600dp | จอแสดงผลของแท็บเล็ตขนาดใหญ่ |
ความกว้างใหญ่พิเศษ | width ≥ 1600dp | โฆษณาบนเดสก์ท็อป |
ความสูงแบบกะทัดรัด | height < 480dp | 99.78% ของโทรศัพท์อยู่ในแนวนอน |
ความสูงปานกลาง | 480dp ≤ ความสูง < 900dp | 96.56% ของแท็บเล็ตในแนวนอน
97.59% ของโทรศัพท์ในแนวตั้ง |
ความสูงที่ขยายออก | height ≥ 900dp | 94.25% ของแท็บเล็ตในโหมดแนวตั้ง |
แม้ว่าการแสดงภาพคลาสขนาดเป็นอุปกรณ์จริงจะมีประโยชน์ แต่คลาสขนาดหน้าต่าง ไม่ได้กำหนดโดยขนาดหน้าจอของอุปกรณ์อย่างชัดเจน คลาสขนาดหน้าต่าง ไม่ได้มีไว้สำหรับตรรกะประเภท isTablet แต่คลาสขนาดหน้าต่างจะกำหนดโดยขนาดหน้าต่างที่แอปพลิเคชันของคุณใช้ได้ ไม่ว่าแอปจะทำงานบนอุปกรณ์ประเภทใดก็ตาม ซึ่งมีผลกระทบที่สำคัญ 2 ประการดังนี้
อุปกรณ์จริงไม่รับประกันคลาสขนาดหน้าต่างที่เฉพาะเจาะจง พื้นที่หน้าจอที่แอปของคุณใช้ได้อาจแตกต่างจากขนาดหน้าจอของ อุปกรณ์ด้วยเหตุผลหลายประการ ในอุปกรณ์เคลื่อนที่ โหมดแยกหน้าจอจะ แบ่งหน้าจอระหว่าง 2 แอปพลิเคชัน ใน ChromeOS แอป Android จะ แสดงในหน้าต่างประเภทเดสก์ท็อปที่ปรับขนาดได้ตามต้องการ อุปกรณ์แบบพับได้อาจมีหน้าจอ 2 ขนาดที่แตกต่างกันซึ่งเข้าถึงได้ โดยการพับหรือกางอุปกรณ์
คลาสขนาดหน้าต่างอาจเปลี่ยนแปลงได้ตลอดอายุการใช้งานของแอป ขณะที่แอปทำงาน การเปลี่ยนการวางแนวของอุปกรณ์ การทำงานแบบมัลติทาสก์ และ การพับ/กางออกอาจเปลี่ยนปริมาณพื้นที่หน้าจอที่ใช้ได้ ด้วยเหตุนี้ คลาสขนาดหน้าต่างจึงเป็นแบบไดนามิก และ UI ของแอปควรปรับเปลี่ยนตามนั้น
Window Size Classes จะแมปกับเบรกพอยท์แบบกะทัดรัด ปานกลาง และขยายใน คำแนะนำเกี่ยวกับเลย์เอาต์ของ Material Design ใช้คลาสขนาดหน้าต่างเพื่อทำการตัดสินใจเกี่ยวกับเลย์เอาต์แอปพลิเคชันระดับสูง เช่น การตัดสินใจว่าจะใช้เลย์เอาต์ Canonical ที่เฉพาะเจาะจงเพื่อใช้ประโยชน์จาก พื้นที่หน้าจอเพิ่มเติมหรือไม่
คุณสามารถคำนวณ
WindowSizeClass
โดยใช้
WindowSizeClass#compute()
ของ Jetpack
ไลบรารี WindowManager ตัวอย่างต่อไปนี้
แสดงวิธีคำนวณคลาสขนาดหน้าต่างและรับการอัปเดตเมื่อใดก็ตามที่
การเปลี่ยนแปลงคลาสขนาดหน้าต่าง:
Kotlin
class MainActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // ... // 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) computeWindowSizeClasses() } }) computeWindowSizeClasses() } private fun computeWindowSizeClasses() { val metrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(this) val width = metrics.bounds.width() val height = metrics.bounds.height() val density = resources.displayMetrics.density val windowSizeClass = WindowSizeClass.compute(width/density, height/density) // COMPACT, MEDIUM, or EXPANDED val widthWindowSizeClass = windowSizeClass.windowWidthSizeClass // COMPACT, MEDIUM, or EXPANDED val heightWindowSizeClass = windowSizeClass.windowHeightSizeClass // Use widthWindowSizeClass and heightWindowSizeClass. } }
Java
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ... // 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); computeWindowSizeClasses(); } }); computeWindowSizeClasses(); } private void computeWindowSizeClasses() { WindowMetrics metrics = WindowMetricsCalculator.getOrCreate() .computeCurrentWindowMetrics(this); int width = metrics.getBounds().width int height = metrics.getBounds().height() float density = getResources().getDisplayMetrics().density; WindowSizeClass windowSizeClass = WindowSizeClass.compute(width/density, height/density) // COMPACT, MEDIUM, or EXPANDED WindowWidthSizeClass widthWindowSizeClass = windowSizeClass.getWindowWidthSizeClass() // COMPACT, MEDIUM, or EXPANDED WindowHeightSizeClass heightWindowSizeClass = windowSizeClass.getWindowHeightSizeClass() // Use widthWindowSizeClass and heightWindowSizeClass. } }
ทดสอบคลาสขนาดหน้าต่าง
เมื่อทำการเปลี่ยนแปลงเลย์เอาต์ ให้ทดสอบลักษณะการทำงานของเลย์เอาต์ในทุกขนาดหน้าต่าง โดยเฉพาะที่ความกว้างของเบรกพอยต์แบบกะทัดรัด ปานกลาง และแบบขยาย
หากมีเลย์เอาต์สำหรับหน้าจอขนาดกะทัดรัดอยู่แล้ว ให้เพิ่มประสิทธิภาพเลย์เอาต์ สำหรับคลาสขนาดความกว้างแบบขยายก่อน เนื่องจากคลาสขนาดนี้มีพื้นที่มากที่สุด สำหรับการเปลี่ยนแปลงเนื้อหาและ UI เพิ่มเติม จากนั้นพิจารณาว่าเลย์เอาต์ใดเหมาะสำหรับ คลาสขนาดความกว้างปานกลาง และพิจารณาเพิ่มเลย์เอาต์เฉพาะ
ขั้นตอนถัดไป
ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีใช้คลาสขนาดหน้าต่างเพื่อสร้างเลย์เอาต์ที่ปรับเปลี่ยนตามพื้นที่โฆษณา/ปรับตาม ได้ที่หัวข้อต่อไปนี้
สำหรับเลย์เอาต์ที่อิงตาม Compose ให้รองรับขนาดการแสดงผลต่างๆ
สำหรับเลย์เอาต์ที่อิงตามมุมมอง: การออกแบบที่ปรับเปลี่ยนตามอุปกรณ์/การออกแบบที่ปรับเปลี่ยนได้ด้วยมุมมอง
ดูข้อมูลเพิ่มเติมเกี่ยวกับสิ่งที่ทำให้แอปยอดเยี่ยมในอุปกรณ์และหน้าจอทุกขนาดได้ที่