FlowRow
และ FlowColumn
เป็นคอมโพสิเบิลที่คล้ายกับ Row
และ Column
แต่แตกต่างกันตรงที่รายการจะไหลไปยังบรรทัดถัดไปเมื่อคอนเทนเนอร์มีพื้นที่ไม่เพียงพอ ซึ่งจะสร้างแถวหรือคอลัมน์หลายรายการ คุณยังควบคุมจำนวนรายการในบรรทัดได้ด้วยการตั้งค่า maxItemsInEachRow
หรือ maxItemsInEachColumn
คุณมักใช้ FlowRow
และ FlowColumn
เพื่อสร้างเลย์เอาต์ที่ตอบสนองได้ เนื้อหาจะไม่ถูกตัดออกหากรายการมีขนาดใหญ่เกินมิติข้อมูลเดียว และการใช้ maxItemsInEach*
ร่วมกับ Modifier.weight(weight)
จะช่วยสร้างเลย์เอาต์ที่เติม/ขยายความกว้างของแถวหรือคอลัมน์ได้เมื่อจำเป็น
ตัวอย่างทั่วไปสำหรับชิปหรือ UI การกรอง
การใช้งานพื้นฐาน
หากต้องการใช้ FlowRow
หรือ FlowColumn
ให้สร้างคอมโพสิเบิลเหล่านี้และวางรายการต่างๆ ไว้ภายในที่ควรเป็นไปตามขั้นตอนมาตรฐาน
@Composable private fun FlowRowSimpleUsageExample() { FlowRow(modifier = Modifier.padding(8.dp)) { ChipItem("Price: High to Low") ChipItem("Avg rating: 4+") ChipItem("Free breakfast") ChipItem("Free cancellation") ChipItem("£50 pn") } }
ตัวอย่างข้อมูลนี้แสดง UI ดังที่แสดงด้านบน โดยระบบจะย้ายรายการไปยังแถวถัดไปโดยอัตโนมัติเมื่อแถวแรกไม่มีพื้นที่เหลือ
ฟีเจอร์ของเลย์เอาต์แบบโฟลว์
เลย์เอาต์แบบโฟลว์มีฟีเจอร์และพร็อพเพอร์ตี้ต่อไปนี้ที่คุณสามารถใช้เพื่อสร้างเลย์เอาต์ต่างๆ ในแอป
การจัดเรียงแกนหลัก: การจัดเรียงแนวนอนหรือแนวตั้ง
กําหนดแกนหลักเป็นแกนที่ใช้วางเลย์เอาต์รายการ (เช่น ในFlowRow
ระบบจะจัดเรียงรายการในแนวนอน) พารามิเตอร์ horizontalArrangement
ใน FlowRow
จะควบคุมวิธีกระจายพื้นที่ว่างระหว่างรายการ
ตารางต่อไปนี้แสดงตัวอย่างการตั้งค่า horizontalArrangement
ในรายการสำหรับ FlowRow
การจัดแนวนอนตั้งค่าไว้เมื่อวันที่ |
ผลลัพธ์ |
|
|
สำหรับ FlowColumn
จะมีตัวเลือกที่คล้ายกันกับ verticalArrangement
โดยค่าเริ่มต้นคือ Arrangement.Top
การจัดเรียงแกนไขว้
แกนไขว้คือแกนที่อยู่ตรงข้ามกับแกนหลัก เช่น ใน FlowRow
นี่เป็นแกนแนวตั้ง หากต้องการเปลี่ยนวิธีจัดเรียงเนื้อหาโดยรวมภายในคอนเทนเนอร์ในแกนแนวตั้ง ให้ใช้ verticalArrangement
สำหรับ FlowRow
และ horizontalArrangement
สำหรับ FlowColumn
สำหรับ FlowRow
ตารางต่อไปนี้แสดงตัวอย่างการตั้งค่า verticalArrangement
ที่แตกต่างกันในรายการ
การจัดแนวตั้งตั้งค่าเป็น |
ผลลัพธ์ |
|
|
สำหรับ FlowColumn
ตัวเลือกที่คล้ายกันจะใช้ได้กับ horizontalArrangement
การจัดเรียงแกนตามขวางเริ่มต้นคือ Arrangement.Start
การจัดแนวรายการแต่ละรายการ
คุณอาจต้องจัดตำแหน่งแต่ละรายการภายในแถวด้วยการจัดแนวที่แตกต่างกัน ซึ่งแตกต่างจาก verticalArrangement
และ
horizontalArrangement
เนื่องจากจะจัดแนวรายการภายในบรรทัดปัจจุบัน คุณใช้ Modifier.align()
กับฟีเจอร์นี้ได้
ตัวอย่างเช่น เมื่อรายการใน FlowRow
มีความสูงต่างกัน แถวจะใช้ความสูงของรายการที่ใหญ่ที่สุดและใช้ Modifier.align(alignmentOption)
กับรายการต่างๆ ดังนี้
การจัดแนวตั้งตั้งค่าเป็น |
ผลลัพธ์ |
|
|
สำหรับ FlowColumn
จะมีตัวเลือกที่คล้ายกัน การจัดแนวเริ่มต้นคือ Alignment.Start
จำนวนรายการสูงสุดในแถวหรือคอลัมน์
พารามิเตอร์ maxItemsInEachRow
หรือ maxItemsInEachColumn
จะกำหนดจำนวนรายการสูงสุดในแกนหลักที่จะแสดงในบรรทัดเดียวก่อนที่จะตัดไปบรรทัดถัดไป ค่าเริ่มต้นคือ Int.MAX_INT
ซึ่งจะอนุญาตรายการได้มากที่สุดเท่าที่จะทำได้ ตราบใดที่ขนาดของรายการพอที่จะใส่ในบรรทัดได้
เช่น การตั้งค่า maxItemsInEachRow
จะบังคับให้เลย์เอาต์เริ่มต้นมีเพียง 3 รายการเท่านั้น ดังนี้
ไม่มีการตั้งค่าสูงสุด |
|
รายการโฟลว์การโหลดแบบ Lazy Loading
ContextualFlowRow
และ ContextualFlowColumn
เป็น FlowRow
และ FlowColumn
เวอร์ชันเฉพาะที่ช่วยให้คุณโหลดเนื้อหาของแถวหรือคอลัมน์ของโฟลว์แบบ Lazy Load ได้ รวมถึงให้ข้อมูลเกี่ยวกับตําแหน่งของสินค้า (ดัชนี หมายเลขแถว และขนาดที่ใช้ได้) เช่น ในกรณีที่สินค้าอยู่ในแถวแรก ซึ่งมีประโยชน์สำหรับชุดข้อมูลขนาดใหญ่และในกรณีที่คุณต้องการข้อมูลตามบริบทเกี่ยวกับรายการ
พารามิเตอร์ maxLines
จะจํากัดจํานวนแถวที่แสดง และแปร overflow
จะระบุสิ่งที่ควรแสดงเมื่อรายการมีจำนวนมากเกินไป ซึ่งช่วยให้คุณระบุ expandIndicator
หรือ collapseIndicator
ที่กำหนดเองได้
เช่น หากต้องการแสดงปุ่ม "+ (จำนวนรายการที่เหลือ)" หรือ "แสดงน้อยลง" ให้ทำดังนี้
val totalCount = 40 var maxLines by remember { mutableStateOf(2) } val moreOrCollapseIndicator = @Composable { scope: ContextualFlowRowOverflowScope -> val remainingItems = totalCount - scope.shownItemCount ChipItem(if (remainingItems == 0) "Less" else "+$remainingItems", onClick = { if (remainingItems == 0) { maxLines = 2 } else { maxLines += 5 } }) } ContextualFlowRow( modifier = Modifier .safeDrawingPadding() .fillMaxWidth(1f) .padding(16.dp) .wrapContentHeight(align = Alignment.Top) .verticalScroll(rememberScrollState()), verticalArrangement = Arrangement.spacedBy(4.dp), horizontalArrangement = Arrangement.spacedBy(8.dp), maxLines = maxLines, overflow = ContextualFlowRowOverflow.expandOrCollapseIndicator( minRowsToShowCollapse = 4, expandIndicator = moreOrCollapseIndicator, collapseIndicator = moreOrCollapseIndicator ), itemCount = totalCount ) { index -> ChipItem("Item $index") }
น้ำหนักสินค้า
น้ำหนักจะเพิ่มขนาดของรายการตามปัจจัยและพื้นที่ว่างในบรรทัดที่มี สิ่งสำคัญคือ FlowRow
และ Row
แตกต่างกันตรงการใช้น้ำหนักในการคำนวณความกว้างของรายการ สำหรับ Rows
น้ำหนักจะอิงตามสินค้าทั้งหมดใน Row
เมื่อใช้ FlowRow
น้ำหนักจะอิงตามรายการในบรรทัดที่วางรายการ ไม่ใช่รายการทั้งหมดในคอนเทนเนอร์ FlowRow
เช่น หากคุณมี 4 รายการที่อยู่บนบรรทัดเดียวกัน โดยแต่ละรายการมีน้ำหนักต่างกัน 1f, 2f, 1f
และ 3f
น้ำหนักทั้งหมดคือ 7f
ระบบจะแบ่งพื้นที่ที่เหลือในแถวหรือคอลัมน์ด้วย 7f
จากนั้นระบบจะคำนวณความกว้างของรายการแต่ละรายการโดยใช้ weight * (remainingSpace / totalWeight)
คุณสามารถใช้รายการ Modifier.weight
และรายการสูงสุดร่วมกับ FlowRow
หรือ FlowColumn
เพื่อสร้างเลย์เอาต์แบบตารางกริด แนวทางนี้มีประโยชน์ต่อการสร้างเลย์เอาต์ที่ปรับเปลี่ยนขนาดให้เหมาะกับอุปกรณ์
ต่อไปนี้เป็นตัวอย่างบางส่วนของสิ่งที่คุณทำได้โดยใช้น้ำหนัก ตัวอย่างหนึ่งคือตารางกริดที่รายการมีขนาดเท่าๆ กัน ดังที่แสดงด้านล่าง
หากต้องการสร้างตารางกริดที่มีขนาดรายการเท่ากัน ให้ทําดังนี้
val rows = 3 val columns = 3 FlowRow( modifier = Modifier.padding(4.dp), horizontalArrangement = Arrangement.spacedBy(4.dp), maxItemsInEachRow = rows ) { val itemModifier = Modifier .padding(4.dp) .height(80.dp) .weight(1f) .clip(RoundedCornerShape(8.dp)) .background(MaterialColors.Blue200) repeat(rows * columns) { Spacer(modifier = itemModifier) } }
สิ่งที่สําคัญคือ หากคุณเพิ่มรายการอื่นและทําซ้ำ 10 ครั้งแทน 9 ครั้ง รายการสุดท้ายจะกินพื้นที่ทั้งคอลัมน์สุดท้าย เนื่องจากน้ำหนักทั้งหมดของทั้งแถวคือ 1f
คุณรวมน้ำหนักกับ Modifiers
อื่นๆ ได้ เช่น
Modifier.width(exactDpAmount), Modifier.aspectRatio(aspectRatio)
หรือ
Modifier.fillMaxWidth(fraction)
ตัวปรับเปลี่ยนเหล่านี้ทั้งหมดจะทำงานร่วมกันเพื่ออนุญาตให้ปรับขนาดรายการภายใน FlowRow
(หรือ FlowColumn
) ให้ปรับเปลี่ยนตามอุปกรณ์
นอกจากนี้ คุณยังสร้างตารางกริดสลับขนาดของรายการต่างๆ ได้โดยให้ 2 รายการใช้พื้นที่ครึ่งหนึ่งของความกว้างแต่ละรายการ และ 1 รายการใช้พื้นที่ความกว้างทั้งหมดของคอลัมน์ถัดไป ดังนี้
ซึ่งทำได้ด้วยโค้ดต่อไปนี้
FlowRow( modifier = Modifier.padding(4.dp), horizontalArrangement = Arrangement.spacedBy(4.dp), maxItemsInEachRow = 2 ) { val itemModifier = Modifier .padding(4.dp) .height(80.dp) .clip(RoundedCornerShape(8.dp)) .background(Color.Blue) repeat(6) { item -> // if the item is the third item, don't use weight modifier, but rather fillMaxWidth if ((item + 1) % 3 == 0) { Spacer(modifier = itemModifier.fillMaxWidth()) } else { Spacer(modifier = itemModifier.weight(0.5f)) } } }
การปรับขนาดแบบเศษส่วน
เมื่อใช้ Modifier.fillMaxWidth(fraction)
คุณจะระบุขนาดของคอนเทนเนอร์ที่สินค้าควรใช้พื้นที่ได้ ซึ่งแตกต่างจากวิธีการทำงานของ Modifier.fillMaxWidth(fraction)
เมื่อใช้กับ Row
หรือ Column
เนื่องจากรายการ Row/Column
จะใช้เปอร์เซ็นต์ของความกว้างที่เหลือแทนที่จะใช้ความกว้างทั้งหมดของคอนเทนเนอร์
ตัวอย่างเช่น โค้ดต่อไปนี้จะให้ผลลัพธ์ที่แตกต่างกันเมื่อใช้ FlowRow
กับ Row
FlowRow( modifier = Modifier.padding(4.dp), horizontalArrangement = Arrangement.spacedBy(4.dp), maxItemsInEachRow = 3 ) { val itemModifier = Modifier .clip(RoundedCornerShape(8.dp)) Box( modifier = itemModifier .height(200.dp) .width(60.dp) .background(Color.Red) ) Box( modifier = itemModifier .height(200.dp) .fillMaxWidth(0.7f) .background(Color.Blue) ) Box( modifier = itemModifier .height(200.dp) .weight(1f) .background(Color.Magenta) ) }
|
|
|
fillMaxColumnWidth()
และ fillMaxRowHeight()
การใช้ Modifier.fillMaxColumnWidth()
หรือ
Modifier.fillMaxRowHeight()
กับรายการภายใน FlowColumn
หรือ FlowRow
จะทําให้รายการในคอลัมน์หรือแถวเดียวกันมีความกว้างหรือความสูงเท่ากับรายการที่ใหญ่ที่สุดในคอลัมน์/แถว
เช่น ตัวอย่างนี้ใช้ FlowColumn
เพื่อแสดงรายการของ Android
desserts คุณจะเห็นความแตกต่างของขนาดความกว้างของรายการแต่ละรายการเมื่อใช้ Modifier.fillMaxColumnWidth()
กับรายการ เทียบกับเมื่อไม่ได้ใช้และรายการมีการตัดขึ้นบรรทัดใหม่
FlowColumn( Modifier .padding(20.dp) .fillMaxHeight() .fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp), verticalArrangement = Arrangement.spacedBy(8.dp), maxItemsInEachColumn = 5, ) { repeat(listDesserts.size) { Box( Modifier .fillMaxColumnWidth() .border(1.dp, Color.DarkGray, RoundedCornerShape(8.dp)) .padding(8.dp) ) { Text( text = listDesserts[it], fontSize = 18.sp, modifier = Modifier.padding(3.dp) ) } } }
|
|
ไม่มีการตั้งค่าการเปลี่ยนแปลงความกว้าง (การตัดรายการ) |
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- ข้อมูลเบื้องต้นเกี่ยวกับการจัดวาง
- ConstraintLayout ใน Compose
- การดำเนินการของเครื่องมือแก้ไข {:#editor-actions}