การรองรับขนาดจอแสดงผลที่ต่างกันช่วยให้ผู้ใช้จำนวนมากและอุปกรณ์ที่หลากหลายเข้าถึงแอปของคุณได้
ออกแบบเลย์เอาต์แอปให้ปรับเปลี่ยนและตอบสนองได้เพื่อรองรับขนาดการแสดงผลมากที่สุด ไม่ว่าจะเป็นหน้าจออุปกรณ์ที่แตกต่างกันหรือหน้าต่างแอปที่แตกต่างกันในโหมดหลายหน้าต่าง เลย์เอาต์ที่ปรับเปลี่ยนได้/ที่ปรับเปลี่ยนได้มอบประสบการณ์การใช้งานที่เพิ่มประสิทธิภาพให้ผู้ใช้โดยไม่คำนึงถึงขนาดของจอแสดงผล ซึ่งช่วยให้แอปของคุณรองรับโทรศัพท์ แท็บเล็ต อุปกรณ์แบบพับได้ อุปกรณ์ ChromeOS การวางแนวแนวตั้งและแนวนอน ตลอดจนการกำหนดค่าการแสดงผลที่ปรับขนาดได้ เช่น โหมดแยกหน้าจอและการแสดงผลแบบหน้าต่างเดสก์ท็อป
เลย์เอาต์ที่ปรับเปลี่ยนตามพื้นที่โฆษณา/ที่ปรับเปลี่ยนจะเปลี่ยนแปลงตามพื้นที่โฆษณาที่มีอยู่ การเปลี่ยนแปลงมีตั้งแต่การปรับเลย์เอาต์เล็กน้อยเพื่อใช้พื้นที่ว่างให้เกิดประโยชน์สูงสุด (การออกแบบที่ปรับเปลี่ยนตามพื้นที่โฆษณา) ไปจนถึงการเปลี่ยนเลย์เอาต์หนึ่งด้วยอีกเลย์เอาต์หนึ่งโดยสมบูรณ์เพื่อให้แอปรองรับขนาดการแสดงผลที่แตกต่างกันได้ดีที่สุด (การออกแบบที่ปรับเปลี่ยนได้)
ในฐานะชุดเครื่องมือ UI แบบประกาศสิ่งที่ต้องการ Jetpack Compose เหมาะอย่างยิ่งสำหรับการออกแบบและการใช้เลย์เอาต์ที่เปลี่ยนแปลงแบบไดนามิกเพื่อแสดงผลเนื้อหาในลักษณะที่แตกต่างกันในจอแสดงผลขนาดต่างๆ
ทำการเปลี่ยนแปลงเลย์เอาต์ขนาดใหญ่สำหรับคอมโพสิเบิลระดับเนื้อหาอย่างชัดเจน
คอมโพสิเบิลระดับแอปและระดับเนื้อหาจะใช้พื้นที่ในการแสดงผลทั้งหมดที่มีให้แอปของคุณ สำหรับคอมโพสิเบิลประเภทเหล่านี้ คุณอาจต้องเปลี่ยนเลย์เอาต์โดยรวมของแอปในจอแสดงผลขนาดใหญ่
หลีกเลี่ยงการใช้ค่าฮาร์ดแวร์จริงในการตัดสินใจเกี่ยวกับเลย์เอาต์ คุณอาจอยากตัดสินใจตามมูลค่าที่จับต้องได้แบบคงที่ (อุปกรณ์เป็นแท็บเล็ตใช่ไหม หน้าจอจริงมีส่วนสัดส่วนภาพแบบใด) แต่คําตอบของคําถามเหล่านี้อาจไม่เป็นประโยชน์ในการระบุพื้นที่ว่างสําหรับ UI
ในแท็บเล็ต แอปอาจทำงานในโหมดหลายหน้าต่าง ซึ่งหมายความว่าแอปอาจแยกหน้าจอกับแอปอื่นอยู่ ในโหมดหน้าต่างเดสก์ท็อปหรือใน ChromeOS แอปอาจอยู่ในหน้าต่างที่ปรับขนาดได้ หรืออาจมีหน้าจอจริงมากกว่า 1 หน้าจอ เช่น อุปกรณ์แบบพับได้ ในทุกกรณีเหล่านี้ ขนาดหน้าจอจริงไม่เกี่ยวข้องกับการตัดสินใจเลือกวิธีแสดงเนื้อหา
แต่คุณควรตัดสินใจตามส่วนจริงของหน้าจอที่จัดสรรให้กับแอปของคุณตามที่เมตริกหน้าต่างปัจจุบันที่ระบุโดยไลบรารี WindowManager ของ Jetpack อธิบาย ดูตัวอย่างวิธีใช้ WindowManager ในแอป Compose ได้ที่ตัวอย่าง JetNews
การปรับเลย์เอาต์ให้เข้ากับพื้นที่แสดงผลที่มีอยู่ยังช่วยลดปริมาณการจัดการพิเศษที่จําเป็นเพื่อรองรับแพลตฟอร์มต่างๆ เช่น ChromeOS และรูปแบบต่างๆ เช่น แท็บเล็ตและอุปกรณ์แบบพับได้
เมื่อคุณกําหนดเมตริกของพื้นที่ว่างสําหรับแอปแล้ว ให้แปลงขนาดดิบเป็นคลาสขนาดหน้าต่างตามที่อธิบายไว้ในใช้คลาสขนาดหน้าต่าง คลาสขนาดหน้าต่างคือจุดหยุดพักที่ออกแบบมาเพื่อรักษาสมดุลระหว่างความเรียบง่ายของตรรกะแอปกับความยืดหยุ่นในการเพิ่มประสิทธิภาพแอปสำหรับขนาดการแสดงผลส่วนใหญ่ คลาสขนาดหน้าต่างหมายถึงหน้าต่างโดยรวมของแอป ดังนั้นให้ใช้คลาสเหล่านี้สำหรับการตัดสินใจเกี่ยวกับเลย์เอาต์ที่ส่งผลต่อเลย์เอาต์โดยรวมของแอป คุณสามารถส่งคลาสขนาดหน้าต่างเป็นสถานะ หรือจะใช้ตรรกะเพิ่มเติมเพื่อสร้างสถานะที่มาจากแหล่งอื่นเพื่อส่งต่อไปยังคอมโพสิชันที่ฝังอยู่ก็ได้
@Composable fun MyApp( windowSizeClass: WindowSizeClass = currentWindowAdaptiveInfo().windowSizeClass ) { // Perform logic on the size class to decide whether to show the top app bar. val showTopAppBar = windowSizeClass.windowHeightSizeClass != WindowHeightSizeClass.COMPACT // MyScreen knows nothing about window sizes, and performs logic based on a Boolean flag. MyScreen( showTopAppBar = showTopAppBar, /* ... */ ) }
แนวทางแบบเป็นชั้นจะจำกัดตรรกะขนาดการแสดงผลไว้ที่ตำแหน่งเดียวแทนที่จะกระจัดกระจายไปทั่วแอปในหลายๆ ตําแหน่งที่ต้องซิงค์กัน ตำแหน่งเดียวจะสร้างสถานะ ซึ่งสามารถส่งต่อไปยังคอมโพสิเบิลอื่นๆ ได้อย่างชัดเจน เช่นเดียวกับสถานะแอปอื่นๆ การส่งสถานะอย่างชัดเจนจะลดความซับซ้อนของคอมโพสิเบิลแต่ละรายการ เนื่องจากคอมโพสิเบิลจะใช้คลาสขนาดหน้าต่างหรือการกําหนดค่าที่ระบุพร้อมกับข้อมูลอื่นๆ
คอมโพสิเบิลที่ฝังไว้อย่างยืดหยุ่นสามารถนำมาใช้ซ้ำได้
คอมโพสิเบิลจะนํากลับมาใช้ซ้ำได้มากขึ้นเมื่อวางได้หลายตําแหน่ง หากต้องวางคอมโพสิเบิลในตำแหน่งที่เจาะจงซึ่งมีขนาดที่เจาะจง คอมโพสิเบิลนั้นอาจใช้ซ้ำในบริบทอื่นไม่ได้ ซึ่งหมายความว่าคอมโพสิชันแบบใช้ซ้ำแต่ละรายการควรหลีกเลี่ยงการพึ่งพาข้อมูลขนาดการแสดงผลส่วนกลางโดยปริยาย
ลองจินตนาการถึงคอมโพสิชันที่ฝังอยู่ซึ่งใช้เลย์เอาต์รายการแบบละเอียด ซึ่งอาจแสดงแผงเดียวหรือ 2 แผงเคียงข้างกัน
การตัดสินใจเกี่ยวกับรายการแบบละเอียดควรเป็นส่วนหนึ่งของเลย์เอาต์โดยรวมของแอป เพื่อให้ระบบส่งต่อการตัดสินใจจากคอมโพสิเบิลระดับเนื้อหา
@Composable fun AdaptivePane( showOnePane: Boolean, /* ... */ ) { if (showOnePane) { OnePane(/* ... */) } else { TwoPane(/* ... */) } }
ในกรณีที่คุณต้องการคอมโพสิเบิลที่จะเปลี่ยนเลย์เอาต์อย่างอิสระตามพื้นที่ในการแสดงผลที่มีอยู่ เช่น การ์ดที่แสดงรายละเอียดเพิ่มเติมหากมีพื้นที่เพียงพอ คุณจะต้องทำอย่างไร คุณต้องการใช้ตรรกะบางอย่างตามขนาดการแสดงผลที่พร้อมใช้งาน แต่จะใช้ขนาดใด
หลีกเลี่ยงการใช้ขนาดหน้าจอจริงของอุปกรณ์ ข้อมูลนี้จะไม่ถูกต้องสำหรับหน้าจอประเภทต่างๆ และจะไม่ถูกต้องหากแอปไม่ได้แสดงแบบเต็มหน้าจอ
เนื่องจากคอมโพสิเบิลไม่ใช่คอมโพสิเบิลระดับเนื้อหา อย่าใช้เมตริกกรอบเวลาปัจจุบันโดยตรง หากวางคอมโพเนนต์โดยมีการเว้นวรรค (เช่น มีการเยื้อง) หรือหากแอปมีคอมโพเนนต์ เช่น แถบนำทางหรือแถบแอป พื้นที่ในการแสดงผลที่ใช้ได้กับคอมโพสิเบิลอาจแตกต่างจากพื้นที่โดยรวมที่ใช้ได้กับแอปอย่างมาก
ใช้ความกว้างที่คอมโพสิเบิลได้รับจริงเพื่อแสดงผล คุณมีตัวเลือก 2 วิธีในการรับความกว้างนั้น
หากต้องการเปลี่ยนตําแหน่งหรือวิธีแสดงเนื้อหา ให้ใช้ชุดตัวแก้ไขหรือเลย์เอาต์ที่กําหนดเองเพื่อให้เลย์เอาต์ปรับเปลี่ยนได้ ซึ่งอาจทำได้ง่ายๆ โดยการใส่องค์ประกอบย่อยให้เต็มพื้นที่ว่างทั้งหมด หรือวางองค์ประกอบย่อยในหลายคอลัมน์หากมีพื้นที่เพียงพอ
หากต้องการเปลี่ยนสิ่งที่แสดง ให้ใช้
BoxWithConstraints
เป็นทางเลือกที่มีประสิทธิภาพมากขึ้นBoxWithConstraints
มีข้อจำกัดการวัดที่คุณสามารถใช้เพื่อเรียกใช้คอมโพสิเบิลต่างๆ ตามพื้นที่โฆษณาที่มีอยู่ อย่างไรก็ตาม การดำเนินการนี้อาจทำให้เสียค่าใช้จ่าย เนื่องจากBoxWithConstraints
จะเลื่อนการจัดวางไว้จนกว่าจะถึงระยะเลย์เอาต์เมื่อทราบข้อจำกัดเหล่านี้ ซึ่งจะทำให้ต้องทำงานมากขึ้นในระหว่างเลย์เอาต์
@Composable fun Card(/* ... */) { BoxWithConstraints { if (maxWidth < 400.dp) { Column { Image(/* ... */) Title(/* ... */) } } else { Row { Column { Title(/* ... */) Description(/* ... */) } Image(/* ... */) } } } }
ตรวจสอบว่าข้อมูลทั้งหมดพร้อมใช้งานสำหรับขนาดการแสดงผลที่แตกต่างกัน
เมื่อใช้คอมโพสิชันที่ใช้ประโยชน์จากพื้นที่แสดงผลเพิ่มเติม คุณอาจต้องการเพิ่มประสิทธิภาพและโหลดข้อมูลเป็นผลกระทบข้างเคียงของขนาดการแสดงผลปัจจุบัน
แต่การดําเนินการดังกล่าวขัดต่อหลักการของโฟลว์ข้อมูลที่เป็นแบบทิศทางเดียว ซึ่งสามารถยกระดับข้อมูลและส่งไปยังคอมโพสิเบิลเพื่อแสดงผลอย่างเหมาะสม คุณควรให้ข้อมูลกับคอมโพสิเบิลมากพอเพื่อให้คอมโพสิเบิลมีเนื้อหาเพียงพอสำหรับขนาดการแสดงผลทุกขนาดเสมอ แม้ว่าระบบอาจไม่ได้ใช้เนื้อหาบางส่วนเสมอไปก็ตาม
@Composable fun Card( imageUrl: String, title: String, description: String ) { BoxWithConstraints { if (maxWidth < 400.dp) { Column { Image(imageUrl) Title(title) } } else { Row { Column { Title(title) Description(description) } Image(imageUrl) } } } }
จากตัวอย่าง Card
โปรดทราบว่าระบบจะส่ง description
ไปยัง Card
เสมอ แม้ว่า description
จะใช้ก็ต่อเมื่อความกว้างอนุญาตให้แสดงได้ แต่ Card
ต้องใช้ description
เสมอ ไม่ว่าจะมีความกว้างเท่าใดก็ตาม
การส่งเนื้อหาที่เพียงพอเสมอจะทำให้เลย์เอาต์แบบปรับเปลี่ยนได้ทำงานได้ง่ายขึ้นเนื่องจากทำให้ไม่มีสถานะมากนักและหลีกเลี่ยงการทริกเกอร์ผลข้างเคียงเมื่อสลับระหว่างขนาดการแสดงผล (ซึ่งอาจเกิดขึ้นเนื่องจากการปรับขนาดหน้าต่าง การเปลี่ยนการวางแนว หรือการพับและการกางอุปกรณ์)
หลักการนี้ยังช่วยให้คงสถานะไว้ได้เมื่อมีการปรับเปลี่ยนเลย์เอาต์ การยกระดับข้อมูลที่ไม่อาจใช้ในขนาดการแสดงผลบางขนาดจะช่วยให้คุณคงสถานะแอปไว้ได้เมื่อขนาดเลย์เอาต์เปลี่ยนแปลง ตัวอย่างเช่น คุณสามารถยกระดับshowMore
Flag แบบบูลีนเพื่อให้ระบบรักษาสถานะแอปไว้เมื่อการปรับขนาดการแสดงผลทําให้เลย์เอาต์สลับไปมาระหว่างการซ่อนและแสดงเนื้อหา
@Composable fun Card( imageUrl: String, title: String, description: String ) { var showMore by remember { mutableStateOf(false) } BoxWithConstraints { if (maxWidth < 400.dp) { Column { Image(imageUrl) Title(title) } } else { Row { Column { Title(title) Description( description = description, showMore = showMore, onShowMoreToggled = { newValue -> showMore = newValue } ) } Image(imageUrl) } } } }
ดูข้อมูลเพิ่มเติม
ดูข้อมูลเพิ่มเติมเกี่ยวกับเลย์เอาต์แบบปรับเปลี่ยนได้ใน Compose ได้ที่แหล่งข้อมูลต่อไปนี้
ตัวอย่างแอป
- CanonicalLayouts เป็นพื้นที่เก็บข้อมูลของรูปแบบการออกแบบที่ผ่านการพิสูจน์แล้วว่ามอบประสบการณ์การใช้งานที่ดีที่สุดบนจอแสดงผลขนาดใหญ่
- JetNews แสดงวิธีออกแบบแอปที่ปรับ UI ให้ใช้ประโยชน์จากพื้นที่แสดงผลที่มีอยู่
- ตอบ คือการตอบสนองต่อตัวอย่างที่รองรับอุปกรณ์เคลื่อนที่ แท็บเล็ต และอุปกรณ์แบบพับได้
- พร้อมใช้งานใน Android แล้วคือแอปที่ใช้เลย์เอาต์ที่ปรับเปลี่ยนได้เพื่อรองรับขนาดการแสดงผลที่แตกต่างกัน
วิดีโอ