FlowRow และ FlowColumn เป็น Composable ที่คล้ายกับ Row และ Column แต่แตกต่างกันตรงที่รายการจะไหลไปยังบรรทัดถัดไปเมื่อคอนเทนเนอร์ไม่มีพื้นที่เหลือ ซึ่งจะสร้างแถวหรือคอลัมน์หลายรายการ นอกจากนี้ คุณยังควบคุมจำนวนรายการในบรรทัดได้ด้วยการตั้งค่า maxItemsInEachRow หรือ maxItemsInEachColumn คุณมักจะใช้ FlowRow และ FlowColumn เพื่อสร้างเลย์เอาต์ที่ปรับเปลี่ยนตามอุปกรณ์ได้ โดยเนื้อหาจะไม่ถูกตัดออกหากรายการมีขนาดใหญ่เกินไปสำหรับมิติข้อมูลเดียว และการใช้ maxItemsInEach* ร่วมกับ Modifier.weight(weight) จะช่วยสร้างเลย์เอาต์ที่เติม/ขยายความกว้างของแถวหรือคอลัมน์เมื่อจำเป็นได้
ตัวอย่างที่พบบ่อยคือชิปหรือ UI การกรอง
FlowRowการใช้งานพื้นฐาน
หากต้องการใช้ FlowRow หรือ FlowColumn ให้สร้าง Composable เหล่านี้และวางรายการไว้ด้านในซึ่งควรเป็นไปตามขั้นตอนมาตรฐาน ดังนี้
@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 จะกำหนดจำนวนรายการสูงสุดในแกนหลักที่อนุญาตใน 1 บรรทัดก่อนที่จะตัดขึ้นบรรทัดใหม่ ค่าเริ่มต้นคือ Int.MAX_INT ซึ่งจะอนุญาตให้มีรายการได้มากที่สุดเท่าที่จะเป็นไปได้ ตราบใดที่ขนาดของรายการพอดีกับบรรทัด
เช่น การตั้งค่า maxItemsInEachRow จะบังคับให้เลย์เอาต์เริ่มต้นมีเพียง 3 รายการเท่านั้น
ไม่ได้ตั้งค่าสูงสุด |
|
|
|
น้ำหนักของสินค้า
น้ำหนักจะขยายรายการตามปัจจัยและพื้นที่ว่างในบรรทัดที่วางรายการนั้น สิ่งสำคัญคือ FlowRow และ Row มีความแตกต่างกันในเรื่องวิธีใช้น้ำหนักเพื่อคำนวณความกว้างของรายการ สำหรับ Rows น้ำหนักจะอิงตามสินค้าทั้งหมดใน Row ใน FlowRow น้ำหนักจะอิงตามรายการในบรรทัดที่มีการวางรายการ ไม่ใช่รายการทั้งหมดในคอนเทนเนอร์ FlowRow
ตัวอย่างเช่น หากคุณมี 4 รายการที่อยู่บนเส้นเดียวกัน โดยแต่ละรายการมีน้ำหนักแตกต่างกันคือ 1f, 2f, 1f และ 3f น้ำหนักรวมจะเป็น 7f พื้นที่ที่เหลือในแถวหรือคอลัมน์จะถูกแบ่งด้วย 7f จากนั้นระบบจะคำนวณความกว้างของแต่ละรายการโดยใช้ weight * (remainingSpace / totalWeight)
คุณสามารถใช้ Modifier.weight และจำนวนรายการสูงสุดร่วมกับ FlowRow หรือ FlowColumn เพื่อสร้างเลย์เอาต์แบบตารางกริดได้ วิธีนี้มีประโยชน์สำหรับการสร้างเลย์เอาต์ที่ปรับเปลี่ยนตามอุปกรณ์ซึ่งจะปรับตามขนาดของอุปกรณ์
ตัวอย่างสิ่งที่คุณทำได้โดยใช้น้ำหนักมีดังนี้ ตัวอย่างหนึ่งคือตารางกริดที่รายการมีขนาดเท่ากัน ดังที่แสดงด้านล่าง
FlowRow เพื่อสร้างตารางกริดหากต้องการสร้างตารางกริดที่มีขนาดรายการเท่ากัน ให้ทำดังนี้
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 ดังนี้
FlowRow เพื่อสร้างตารางกริดโดยให้รายการสุดท้ายมีความกว้างเต็มคุณสามารถรวมน้ำหนักกับModifiersอื่นๆ เช่น Modifier.width(exactDpAmount), Modifier.aspectRatio(aspectRatio) หรือ Modifier.fillMaxWidth(fraction) ได้ ตัวแก้ไขเหล่านี้ทั้งหมดทำงานร่วมกันเพื่อให้สามารถปรับขนาดรายการแบบตอบสนองภายใน FlowRow (หรือ FlowColumn) ได้
นอกจากนี้ คุณยังสร้างตารางกริดสลับกันของรายการขนาดต่างๆ ได้ โดยที่ 2 รายการใช้ความกว้างครึ่งหนึ่ง และ 1 รายการใช้ความกว้างเต็มของคอลัมน์ถัดไป ดังนี้
FlowRow ที่มีแถวขนาดสลับกันคุณสามารถทำได้โดยใช้โค้ดต่อไปนี้
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 คุณจะเห็นความแตกต่างของความกว้างของแต่ละรายการเมื่อใช้ 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 ปิดอยู่
- ข้อมูลเบื้องต้นเกี่ยวกับเลย์เอาต์ Compose
- ConstraintLayout ใน Compose
- การดำเนินการของผู้แก้ไข {:#editor-actions}