คุณสามารถกำหนดค่าคอนเทนเนอร์ Grid เพื่อสร้างเลย์เอาต์ที่ยืดหยุ่น ซึ่งตอบสนองต่อขนาดหน้าจอและประเภทเนื้อหาต่างๆ หน้านี้จะอธิบายวิธีการทำสิ่งต่อไปนี้
- กำหนดตารางกริด: ตั้งค่าโครงสร้างพื้นฐานของแถวและคอลัมน์
- วางรายการในตารางกริด: ทำความเข้าใจวิธีวางรายการในเซลล์ตารางกริดและวิธีเปลี่ยนทิศทางการไหล
- จัดการการกำหนดขนาดแทร็ก: ใช้การกำหนดขนาดแบบคงที่ เปอร์เซ็นต์ แบบยืดหยุ่น และแบบแท้จริงเพื่อกำหนดขนาดแทร็ก
- กำหนดช่องว่าง: จัดการ "ช่องว่าง" ระหว่างแถวและคอลัมน์
กำหนดตารางกริด
ตารางกริดประกอบด้วยคอลัมน์และแถว
Composable Grid มีพารามิเตอร์ config
ที่ยอมรับ Lambda เพื่อกำหนดคอลัมน์และแถว
ภายใน GridConfigurationScope
ตัวอย่างต่อไปนี้กำหนดตารางกริดที่มี 3 แถวและ 2 คอลัมน์
แต่ละคอลัมน์มีขนาดคงที่ที่ระบุใน Dp
Grid( config = { repeat(2) { column(160.dp) } repeat(3) { row(90.dp) } } ) { }
วางรายการในตารางกริด
Grid จะนำองค์ประกอบ UI
ใน Lambda content ไปวางไว้ในเซลล์ตารางกริด
กริดจะจัดวางรายการโดยไม่คำนึงถึง
ว่าคุณได้กำหนดแถวและคอลัมน์อย่างชัดเจนหรือไม่
โดยค่าเริ่มต้น
Grid จะพยายามวางองค์ประกอบ UI ในตารางกริดที่ว่างในแถว
หากทำไม่ได้ ก็จะวางในตารางกริดที่ว่างในแถวถัดไป
หากไม่มีเซลล์ว่าง Grid จะสร้างแถวใหม่
ในตัวอย่างต่อไปนี้ กริดมีเซลล์กริด 6 เซลล์
และวางการ์ดลงในแต่ละเซลล์ (รูปที่ 1)
แต่ละเซลล์ในตารางมีขนาด 160dp x 90dp
ทำให้ขนาดตารางทั้งหมดเป็น 320dp x 270dp
Grid( config = { repeat(2) { column(160.dp) } repeat(3) { row(90.dp) } } ) { Card1() Card2() Card3() Card4() Card5() Card6() }
หากต้องการเปลี่ยนลักษณะการทำงานเริ่มต้นนี้เป็นการกรอกข้อมูลตามคอลัมน์
ให้ตั้งค่าพร็อพเพอร์ตี้ flow เป็น GridFlow.Column
Grid( config = { repeat(2) { column(160.dp) } repeat(3) { row(90.dp) } gap(8.dp) flow = GridFlow.Column // Grid tries to place items to fill the column }, ) { Card1() Card2() Card3() Card4() Card5() Card6() }
GridFlow.Row (ซ้าย) และ GridFlow.Column (ขวา)
จัดการการปรับขนาดแทร็ก
แถวและคอลัมน์จะเรียกรวมกันว่าแทร็กกริด คุณระบุขนาดของแทร็กตารางกริดได้โดยใช้วิธีใดวิธีหนึ่งต่อไปนี้
- คงที่ (
Dp): จัดสรรขนาดที่เฉพาะเจาะจง (เช่นcolumn(180.dp)) - เปอร์เซ็นต์ (
Float): จัดสรรเปอร์เซ็นต์ของพื้นที่ว่างทั้งหมด จาก0.0fถึง1.0f(เช่นrow(0.5f)สำหรับ 50%) - ยืดหยุ่น (
Fr): จัดสรรพื้นที่ที่เหลือตามสัดส่วนหลังจากคำนวณแทร็กแบบคงที่ และแบบเปอร์เซ็นต์ เช่น หากตั้งค่า 2 แถวเป็น1.frและ3.frแถวหลังจะได้รับความสูงที่เหลือ 75% - Intrinsic: ปรับขนาดแทร็กตามเนื้อหาภายใน ดูข้อมูลเพิ่มเติมได้ที่กำหนดขนาดแทร็กตารางกริดโดยค่าเริ่มต้น
ตัวอย่างต่อไปนี้ใช้ตัวเลือกการปรับขนาดแทร็กต่างๆ เพื่อกำหนดความสูงของแถว
Grid( config = { column(1f) row(100.dp) row(0.2f) row(1.fr) row(GridTrackSize.Auto) }, modifier = Modifier.height(480.dp) ) { PastelRedCard("Fixed(100.dp)") PastelGreenCard("Percentage(0.2f)") PastelBlueCard("Flex(1.fr)") PastelYellowCard("Auto") }
Grid
กำหนดขนาดขั้นต่ำสำหรับแทร็กกริดแบบยืดหยุ่น
เมื่อคอนเทนเนอร์กริดไม่มีพื้นที่เหลือ
แทร็กแบบยืดหยุ่นมาตรฐานจะหดเหลือ 0.dp ได้
หากต้องการป้องกันปัญหานี้และตรวจสอบว่าเนื้อหาไม่ถูกบีบอัด
ให้ใช้ GridTrackSize.MinMax
เพื่อบังคับใช้ขนาดขั้นต่ำที่ชัดเจนในขณะที่ยังคงความยืดหยุ่นของแทร็กไว้
ตัวอย่างต่อไปนี้จัดสรรอย่างน้อย 100.dp ให้กับแถวแรก
Grid( config = { column(1f) // The first row has a minimum height of 100.dp and can expand to // the half of the remaining space. row(GridTrackSize.MinMax(100.dp, 1.fr)) // The second row takes the half of the remaining space. row(1.fr) // The third row has a fixed height of 200.dp. row(200.dp) }, modifier = Modifier.size(360.dp) // Total grid height is 360.dp ) { PastelRedCard("MinMax(100.dp, 1.fr)") PastelGreenCard("Flex(1.fr)") PastelBlueCard("Fixed(200.dp)") }
100.dp
กำหนดขนาดแทร็กกริดขั้นต่ำเพื่อวางรายการแบบเลซี่
แทร็กที่ยืดหยุ่นมาตรฐานจะค้นหาขนาดโดยธรรมชาติของ
องค์ประกอบย่อยโดยอัตโนมัติเพื่อกำหนดขนาดฐาน
อย่างไรก็ตาม Jetpack Compose ไม่อนุญาตให้ค้นหาขนาดโดยธรรมชาติของ
SubcomposeLayout ซึ่งเป็นส่วนประกอบแบ็กเอนด์
เช่น LazyColumn และ LazyRow
การวางรายการแบบเลื่อนขี้เกียจไว้ในแทร็กแบบยืดหยุ่นมาตรฐานจะทำให้เกิดข้อขัดข้อง IllegalStateException
หากต้องการวางรายการแบบเลื่อนขี้เกียจภายในแทร็กกริดที่ยืดหยุ่นได้อย่างปลอดภัย
ให้ใช้ MinMax ที่มีขนาดขั้นต่ำที่ชัดเจน (เช่น 0.dp)
เพื่อข้ามการวัดค่าโดยธรรมชาติ
Grid( config = { column(1f) // The first row's height is determined by the height of the Text composable. row(GridTrackSize.Auto) // The second row occupies the remaining space, allowing the LazyColumn to scroll. row(GridTrackSize.MinMax(0.dp, 1.fr)) gap(8.dp) }, modifier = Modifier.size(width = 170.dp, height = 240.dp) ) { Text("LazyColumn in a Grid") // The LazyColumn is placed in the second row, filling the remaining space. LazyColumn(verticalArrangement = Arrangement.spacedBy(4.dp)) { items(100) { number -> PastelGreenCard("Card $number") } } }
LazyColumn ในเซลล์ตาราง
กำหนดขนาดแทร็กตารางกริดโดยอัตโนมัติ
คุณสามารถใช้การกำหนดขนาดโดยอิงตามเนื้อหาสำหรับ Grid
เมื่อต้องการให้เลย์เอาต์ปรับตามเนื้อหา
แทนที่จะบังคับให้เลย์เอาต์อยู่ในคอนเทนเนอร์แบบคงที่
ขนาดแทร็กตารางกริดจะกำหนดด้วยค่าต่อไปนี้
GridTrackSize.MaxContent: ใช้ขนาดสูงสุดโดยธรรมชาติของเนื้อหา (เช่น ความกว้างจะกำหนดตามความยาวเต็มของข้อความ ในบล็อกข้อความที่ไม่มีการตัดคำ)GridTrackSize.MinContent: ใช้ขนาดเนื้อหาขั้นต่ำโดยธรรมชาติ (เช่น ความกว้างจะกำหนดโดยคำที่ยาวที่สุดในบล็อกข้อความ)GridTrackSize.Auto: ใช้ขนาดที่ยืดหยุ่นสำหรับแทร็ก ที่ปรับตามพื้นที่ว่างที่มี โดยค่าเริ่มต้นจะทำงานเหมือนMaxContentแต่จะย่อและรวมเนื้อหาให้พอดีกับคอนเทนเนอร์ระดับบนสุด
ตัวอย่างต่อไปนี้จะวางข้อความ 2 รายการไว้ข้างกัน ระบบจะกำหนดขนาดคอลัมน์สำหรับข้อความแรก ตามความกว้างขั้นต่ำที่จำเป็นในการแสดงข้อความ และความกว้างของคอลัมน์ที่สองจะขึ้นอยู่กับความกว้างสูงสุดที่จำเป็นของข้อความ
Grid( config = { column(GridTrackSize.MinContent) column(GridTrackSize.MaxContent) row(1.0f) }, modifier = Modifier.width(480.dp) ) { Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras imperdiet.") Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras imperdiet.") }
กำหนดช่องว่างระหว่างแถวและคอลัมน์
เมื่อปรับขนาดแทร็กกริดแล้ว
คุณจะแก้ไขช่องว่างของกริดเพื่อปรับระยะห่างระหว่างแทร็กได้
คุณระบุช่องว่างระหว่างคอลัมน์ได้ด้วยฟังก์ชัน columnGap
และช่องว่างระหว่างแถวด้วย rowGap ในตัวอย่างต่อไปนี้
มี16dpช่องว่างระหว่างแต่ละแถว
และ8dpช่องว่างระหว่างแต่ละคอลัมน์ (รูปที่ 5)
Grid( config = { repeat(2) { column(160.dp) } repeat(3) { row(90.dp) } rowGap(16.dp) columnGap(8.dp) } ) { Card1() Card2() Card3() Card4() Card5() Card6() }
นอกจากนี้ คุณยังใช้ฟังก์ชันอำนวยความสะดวก gap
เพื่อกำหนดช่องว่างที่มีขนาดคอลัมน์และแถวเท่ากัน
และกำหนดขนาดคอลัมน์และช่องว่างแยกกันโดยใช้ฟังก์ชันเดียวได้ด้วย
โค้ดต่อไปนี้จะเพิ่มช่องว่าง 8dp ลงในตารางกริด
Grid( config = { repeat(2) { column(160.dp) } repeat(3) { row(90.dp) } gap(8.dp) // Equivalent to columnGap(8.dp) and rowGap(8.dp) } ) { Card1() Card2() Card3() Card4() Card5() Card6() }
กำหนดพื้นที่กริดด้วยพื้นที่ที่มีชื่อ
พื้นที่ที่มีชื่อช่วยให้คุณแนบชื่อกับกลุ่มของเซลล์ตารางกริดได้ ซึ่งเรียกว่าพื้นที่ตารางกริด คุณสามารถใช้ชื่อเหล่านี้แทนดัชนีพิกัด เมื่อวางองค์ประกอบ UI ในตารางกริด
การใช้พื้นที่ที่มีชื่อมีประโยชน์หลัก 2 ประการต่อความสามารถในการอ่านโค้ด ดังนี้
- เมื่อกำหนดเลย์เอาต์ตารางแล้ว วัตถุประสงค์และตำแหน่งของเนื้อหาที่คาดไว้จะชัดเจน
- เมื่อเพิ่มเนื้อหา วัตถุประสงค์ของเนื้อหานั้นจะชัดเจน
หากต้องการจัดระเบียบเลย์เอาต์ที่ซับซ้อนให้ชัดเจน คุณสามารถแยกโครงสร้างกริดจริงออกจากตำแหน่งย่อยได้โดยกำหนดพื้นที่กริดเชิงความหมาย
ภายใน config lambda ให้ใช้ฟังก์ชัน area ใน
GridConfigurationScope เพื่อลงทะเบียนพื้นที่ที่มีชื่อในตารางกริด
จากนั้นคุณจะกำหนด Composable ย่อยให้กับพื้นที่เหล่านี้ได้
โดยใช้ตัวแก้ไข gridItem
พร้อมตัวระบุพื้นที่ที่เกี่ยวข้อง ฟังก์ชัน area จะแมป
ตัวระบุเชิงความหมาย (เช่น ค่าคลาส enum หรือคีย์สตริง) กับ
ชุดพิกัดกริดทางกายภาพ เส้นตารางและดัชนีเป็นแบบอิงตาม 1
(กล่าวคือ แถวแรกคือ 1 และคอลัมน์แรกคือ 1)
เช่น คุณกำหนดตารางกริดที่มีรหัสพื้นที่ 4 รายการ ดังนี้
/** * An enum representing the IDs for named areas within the grid. */ enum class GridAreaNames { Area1, Area2, Area3, Area4 }
ระบุชื่อพื้นที่โดยใช้พารามิเตอร์ areaId พร้อมกับพิกัดเซลล์และช่วงของพื้นที่
ตัวแก้ไข gridItem ใช้ areaId เป็นคีย์
เพื่อกำหนดแต่ละรายการย่อยให้กับพื้นที่กริดที่กำหนด
ดังที่แสดงในตัวอย่างต่อไปนี้
Grid( config = { // Define a single column that takes all available width. repeat(2) { column(0.5f) } // Define four rows, each taking 25% of the total height. repeat(4) { row(0.25f) } // Define named grid areas by associating an areaId with specific row and column indices. // Row and column indices are 1-based. area(areaId = GridAreaNames.Area1, row = 1, column = 1, columnSpan = 2) area(areaId = GridAreaNames.Area2, row = 2, column = 1, rowSpan = 3) area(areaId = GridAreaNames.Area3, rows = 2..3, columns = 2..2) area(areaId = GridAreaNames.Area4, row = 4, column = 2) gap(4.dp) }, modifier = Modifier.size(360.dp) ) { PastelRedCard( "Area 1", // Use Modifier.gridItem(areaId) to place this composable into the // grid area defined with the matching ID in the config block. modifier = Modifier.gridItem(areaId = GridAreaNames.Area1) ) PastelGreenCard( "Area 2", modifier = Modifier.gridItem(areaId = GridAreaNames.Area2) ) PastelBlueCard( "Area 3", modifier = Modifier.gridItem(areaId = GridAreaNames.Area3) ) PastelYellowCard( "Area 4", modifier = Modifier.gridItem(areaId = GridAreaNames.Area4) ) }
การใช้พื้นที่ที่มีชื่อช่วยให้คุณจัดระเบียบใหม่หรือปรับตารางเลย์เอาต์จริง (เช่น เปลี่ยนขนาดแถว คอลัมน์ หรือแทร็ก) ใน config lambda
โดยไม่ต้องแก้ไขลำดับหรือพารามิเตอร์ของ Composable ย่อย