Composable Grid จะสร้างเลย์เอาต์หน้าจอแบบ 2 มิติเชิงโครงสร้าง
Grid กำหนดโครงสร้างเลย์เอาต์ที่ตอบสนองโดยใช้แทร็ก (แถวและคอลัมน์) และช่องว่างที่กำหนดไว้อย่างชัดเจนเป็นสถาปัตยกรรมพื้นฐานของ UI
เนื่องจาก Grid เป็นคอนเทนเนอร์เชิงโครงสร้างมากกว่าคอนเทนเนอร์ที่โหลดแบบ Lazy Loading คุณจึงต้อง
กำหนดองค์ประกอบทุกรายการที่วางไว้ภายในอย่างชัดเจนโดยไม่ต้องรีไซเคิลรายการเมื่อเลื่อน
ด้วยเหตุนี้ การแสดงผลชุดข้อมูลขนาดใหญ่หรือชุดข้อมูลแบบไดนามิกภายใน Grid โดยตรงอาจทำให้เกิดปัญหาคอขวดด้านประสิทธิภาพ เนื่องจากรายการทั้งหมดจะประกอบพร้อมกัน
หากต้องการแสดงคอลเล็กชันข้อมูลขนาดใหญ่ภายในเลย์เอาต์หน้าจอที่มีโครงสร้าง ให้ฝังคอมโพเนนต์แบบเลซี เช่น LazyColumn หรือ LazyRow ในเซลล์ Grid
แต่โปรดทราบว่าแทร็กที่ยืดหยุ่น (ที่มีข้อกำหนด เช่น 1.fr) จะค้นหาขนาดที่แท้จริงขององค์ประกอบย่อย
เนื่องจาก SubcomposeLayout ไม่รองรับการส่งผ่านการวัดผลโดยธรรมชาติ
การวางรายการแบบ Lazy ไว้ในแทร็กที่ยืดหยุ่นจะทําให้เกิดข้อขัดข้อง IllegalStateException หากต้องการวางรายการแบบเลื่อนอย่างปลอดภัยภายในแทร็กกริดที่ยืดหยุ่น
ได้ คุณต้องใช้การกำหนดขนาด GridTrackSize.MinMax (เช่น minmax(0.dp, 1.fr))
เพื่อข้ามการวัดค่าโดยธรรมชาติ
LazyColumnที่ฝังไว้สำหรับเนื้อหาแนวทางปฏิบัติแนะนำ
- ใช้รายการแบบเลซี่แทนลูปขนาดใหญ่ที่ชัดเจน: หากต้องการแสดงชุดข้อมูลขนาดใหญ่หรือชุดข้อมูลแบบไดนามิกภายใน
Gridที่มีโครงสร้าง ให้ฝังคอมโพเนนต์แบบเลซี่ (โดยปกติคือLazyColumnหรือLazyRow) ไว้ในเซลล์ตารางกริดที่เฉพาะเจาะจงแทนการสร้างลูปขนาดใหญ่ที่ชัดเจนในรายการ เนื่องจากGridไม่รีไซเคิลรายการและมีขีดจำกัดที่ 1,000 แทร็ก - ใช้
MinMaxtrack sizing for lazy lists: เนื่องจากLazyColumnและLazyRowไม่รองรับการวัดค่าที่แท้จริง (ดูSubcomposeLayout) ให้ใช้GridTrackSize.MinMaxในแทร็กที่ยืดหยุ่นซึ่งโฮสต์คอมโพเนนต์แบบเลซีเพื่อข้าม การวัดค่าที่แท้จริงอย่างปลอดภัย
ส่วนผสม
Grid: เลย์เอาต์ที่ประกอบได้ซึ่งวางรายการในโครงสร้างตารางกริดแบบ 2 มิติ ที่กำหนดค่าโดยใช้แทร็กแถวและคอลัมน์ที่ชัดเจนLazyColumn: รายการที่เลื่อนในแนวตั้งซึ่งประกอบและนำกลับมาใช้ใหม่เฉพาะ รายการที่มองเห็นได้บนหน้าจอในขณะนั้นGridTrackSize.MinMax: ติดตามพร็อพเพอร์ตี้การปรับขนาดที่กำหนดขอบเขตที่ยืดหยุ่น (minและmax) เพื่อโฮสต์คอมโพเนนต์ที่โหลดแบบ Lazy อย่างปลอดภัยโดยไม่ทำให้เกิดข้อขัดข้องในการวัดรันไทม์gridItem: เขียนส่วนขยายModifierที่กำหนดองค์ประกอบ UI ย่อยให้กับเซลล์หรือพื้นที่ที่มีชื่อเฉพาะภายในGrid
ขั้นตอน
จัดโครงสร้างเลย์เอาต์หน้าจอโดยกำหนดตัวระบุพื้นที่เชิงความหมาย กำหนดค่า
แทร็กกริดด้วยminmaxการกำหนดขนาดเพื่อความเข้ากันได้ของรายการแบบเลื่อน และฝัง
LazyColumnภายในพื้นที่เนื้อหากริด
1. กำหนดค่าแทร็กตารางกริดและพื้นที่ที่มีชื่อ
สร้างenumคลาสเพื่อแสดงถึงภูมิภาคที่แตกต่างกันของเลย์เอาต์หน้าจอ
และกำหนดGridConfigurationScope Lambda สำหรับแทร็กเลย์เอาต์และพื้นที่ที่มีชื่อ
ใช้ GridTrackSize.MaxContent สำหรับแถวส่วนหัวและส่วนท้ายเพื่อให้พอดีกับขนาดเนื้อหา และใช้ minmax(0.dp, 1.fr) สำหรับแทร็กเนื้อหาที่โฮสต์รายการแบบ Lazy Loading เพื่อจัดสรรพื้นที่ที่ยืดหยุ่นได้โดยไม่ต้องค้นหาการวัดค่าภายในที่ไม่รองรับ
enum class ScreenArea { Header, Content, Footer } val lazyConfig: GridConfigurationScope.() -> Unit = { column(minmax(0.dp, 1.fr)) row(GridTrackSize.MaxContent) row(minmax(0.dp, 1.fr)) row(GridTrackSize.MaxContent) area(ScreenArea.Header, row = 1, column = 1) area(ScreenArea.Content, row = 2, column = 1) area(ScreenArea.Footer, row = 3, column = 1) gap(8.dp) }
2. วางคอมโพเนนต์แบบคงที่ในตารางกริด
ใน Composable ให้ส่ง lazyConfig ไปยังคอนเทนเนอร์ Grid ภายในcontent lambda ให้วางคอมโพเนนต์แบบคงที่ (Header และ Footer) และจัดตำแหน่งโดยใช้ Modifier.gridItem() พร้อมตัวระบุพื้นที่ที่เกี่ยวข้อง
3. ฝัง LazyColumn ในพื้นที่เนื้อหา
ในเซลล์เนื้อหา ให้ฝัง LazyColumn โดยใช้ Modifier.gridItem(ScreenArea.Content)
เนื่องจากมีการกำหนดค่าแทร็กเนื้อหาด้วย minmax(0.dp, 1.fr) ในขั้นตอนที่ 1
LazyColumn จึงสามารถวัดและรีไซเคิลรายการเมื่อเลื่อนได้อย่างปลอดภัยโดยไม่ต้องค้นหามิติข้อมูลภายในที่ไม่รองรับ
@Composable fun GridWithLazyColumn( modifier: Modifier = Modifier, items: List<String> = emptyList(), ) { Grid( modifier = modifier.fillMaxSize(), config = lazyConfig ) { Text("Header", Modifier.gridItem(ScreenArea.Header).padding(16.dp)) Text("Footer", Modifier.gridItem(ScreenArea.Footer).padding(16.dp)) // LazyColumn placed in the content area for large datasets LazyColumn( modifier = Modifier .gridItem(ScreenArea.Content) .fillMaxSize(), verticalArrangement = Arrangement.spacedBy(8.dp) ) { items(items) { item -> Text(item, Modifier.padding(16.dp)) } } } }
ผลลัพธ์
เลย์เอาต์หน้าจอของคุณใช้ Grid API เพื่อกำหนดโครงสร้างหน้าเว็บแบบ 2 มิติโดยรวม
ในขณะที่ฝัง LazyColumn ในแทร็กที่ยืดหยุ่น
พร้อมการกำหนดขนาด minmax เพื่อรีไซเคิลรายการได้อย่างมีประสิทธิภาพและหลีกเลี่ยงข้อยกเว้นขณะรันไทม์