Composable Grid จะสร้างเลย์เอาต์หน้าจอแบบ 2 มิติที่มีโครงสร้าง
Grid กำหนดโครงสร้างเลย์เอาต์ที่ปรับเปลี่ยนตามอุปกรณ์โดยใช้แทร็ก (แถวและคอลัมน์) และช่องว่างที่กำหนดไว้อย่างชัดเจนเป็นสถาปัตยกรรมพื้นฐานของ UI
เนื่องจาก Grid เป็นคอนเทนเนอร์เชิงโครงสร้าง ไม่ใช่คอนเทนเนอร์แบบ Lazy Loading คุณจึงต้องกำหนดองค์ประกอบทุกรายการที่วางไว้ภายในอย่างชัดเจนโดยไม่ต้องรีไซเคิลรายการเมื่อเลื่อน
ด้วยเหตุนี้ การแสดงผลชุดข้อมูลขนาดใหญ่หรือแบบไดนามิกภายใน Grid โดยตรงจึงอาจทำให้เกิดคอขวดด้านประสิทธิภาพเนื่องจากรายการทั้งหมดจะคอมโพสพร้อมกัน
หากต้องการแสดงคอลเล็กชันข้อมูลขนาดใหญ่ภายในเลย์เอาต์หน้าจอที่มีโครงสร้าง ให้ฝังคอมโพเนนต์แบบ Lazy เช่น LazyColumn หรือ LazyRow ในเซลล์ Grid
แต่โปรดทราบว่าแทร็กที่ยืดหยุ่น (ซึ่งมีข้อกำหนด เช่น 1.fr) จะค้นหาขนาดที่แท้จริงขององค์ประกอบย่อย เนื่องจาก SubcomposeLayout ไม่รองรับการส่งผ่านการวัดค่าภายใน การวางรายการแบบ Lazy ภายในแทร็กที่ยืดหยุ่นจึงทำให้เกิดข้อขัดข้อง IllegalStateException หากต้องการวางรายการแบบ Lazy ภายในแทร็กตารางกริดแบบยืดหยุ่นอย่างปลอดภัย คุณต้องใช้การปรับขนาด GridTrackSize.MinMax (เช่น minmax(0.dp, 1.fr)) เพื่อข้ามขั้นตอนการวัดค่าภายใน
LazyColumn แบบฝังสำหรับเนื้อหาแนวทางปฏิบัติแนะนำ
- ใช้ Lazy List แทนลูปที่ชัดเจนขนาดใหญ่: หากต้องการแสดงชุดข้อมูลขนาดใหญ่หรือแบบไดนามิกภายใน
Gridที่มีโครงสร้าง ให้ฝังคอมโพเนนต์ Lazy (โดยทั่วไปคือLazyColumnหรือLazyRow) ไว้ภายในเซลล์ตารางกริดที่เฉพาะเจาะจง แทนที่จะสร้างลูปที่ชัดเจนขนาดใหญ่เหนือรายการ เนื่องจากGridไม่รีไซเคิลรายการและมีขีดจำกัดที่ 1,000 แทร็ก - ใช้การปรับขนาดแทร็ก
MinMaxสำหรับ Lazy List: เนื่องจากLazyColumnและLazyRowไม่รองรับการส่งผ่านการวัดภายใน (ดูSubcomposeLayout) ให้ใช้GridTrackSize.MinMaxในแทร็กที่ยืดหยุ่นซึ่งโฮสต์คอมโพเนนต์ Lazy เพื่อข้ามการวัดภายในอย่างปลอดภัย
ส่วนผสม
Grid: เลย์เอาต์ Composable ที่วางรายการในโครงสร้างตารางกริด 2 มิติซึ่งกำหนดค่าโดยใช้แทร็กแถวและคอลัมน์ที่ชัดเจนLazyColumn: รายการที่เลื่อนในแนวตั้งซึ่งเขียนและรีไซเคิลเฉพาะรายการที่มองเห็นได้บนหน้าจอในขณะนั้นGridTrackSize.MinMax: พร็อพเพอร์ตี้การปรับขนาดแทร็กที่กำหนดขอบเขตที่ยืดหยุ่น (minและmax) เพื่อโฮสต์คอมโพเนนต์แบบ Lazy ได้อย่างปลอดภัยโดยไม่ทำให้เกิดข้อขัดข้องในการวัดรันไทม์gridItem: ส่วนขยาย ComposeModifierที่กำหนดองค์ประกอบ UI ย่อยให้กับเซลล์ที่เฉพาะเจาะจงหรือพื้นที่ที่มีชื่อภายในGrid
ขั้นตอน
จัดโครงสร้างเลย์เอาต์หน้าจอโดยกำหนดตัวระบุพื้นที่เชิงความหมาย กำหนดค่าแทร็กตารางกริดด้วยการปรับขนาด minmax เพื่อให้เข้ากันได้กับ Lazy List และฝัง LazyColumn ไว้ในพื้นที่เนื้อหาตารางกริด
1. กำหนดค่าแทร็กตารางกริดและพื้นที่ที่มีชื่อ
สร้างคลาส enum เพื่อแสดงถึงพื้นที่ต่างๆ ของเลย์เอาต์หน้าจอ และกำหนดแลมบ์ดา GridConfigurationScope สำหรับแทร็กเลย์เอาต์และพื้นที่ที่มีชื่อ ใช้ GridTrackSize.MaxContent สำหรับแถวส่วนหัวและส่วนท้ายเพื่อให้พอดีกับขนาดเนื้อหา และใช้ minmax(0.dp, 1.fr) สำหรับแทร็กเนื้อหาที่โฮสต์รายการแบบ Lazy เพื่อจัดสรรพื้นที่ที่ยืดหยุ่นโดยไม่ต้องค้นหาการวัดค่าภายในที่ไม่รองรับ ดังนี้
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 ให้วางคอมโพเนนต์แบบคงที่ (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 เพื่อรีไซเคิลรายการในลิสต์อย่างมีประสิทธิภาพและหลีกเลี่ยงข้อยกเว้นรันไทม์