LazyRow — เป็นฟังก์ชัน composable ใน Jetpack Compose สำหรับสร้างรายการแนวนอนที่มีการโหลดแบบขี้เกียจขององค์ประกอบ แตกต่างจาก Row ตรงที่ LazyRow จะสร้างเฉพาะองค์ประกอบที่มองเห็นและนำกลับมาใช้ใหม่ระหว่างการเลื่อนแนวนอน ตาม Google Android Documentation, 2025 LazyRow เป็นเวอร์ชันแนวนอนของ LazyColumn และมีประสิทธิภาพสำหรับภาพหมุน แกลเลอรี และเมนูแนวนอนในแอปพลิเคชันมือถือ
ประเด็นสำคัญ
LazyRow — เป็นฟังก์ชัน composable ที่ใช้รายการแนวนอนที่เลื่อนได้พร้อมการโหลดแบบขี้เกียจขององค์ประกอบ แตกต่างจาก Row ที่แสดงผลองค์ประกอบย่อยทั้งหมดพร้อมกัน LazyRow จะสร้างเฉพาะองค์ประกอบที่มองเห็นในพื้นที่รับชม
LazyRow ทำงานบนหลักการเดียวกับ LazyColumn แต่จัดวางองค์ประกอบในแนวนอน เมื่อเลื่อนไปทางซ้ายหรือขวา องค์ประกอบที่ออกจากพื้นที่รับชมจะถูกนำกลับมาใช้ใหม่เพื่อแสดงองค์ประกอบใหม่ นี่เป็นสิ่งสำคัญสำหรับแกลเลอรีที่มีรูปภาพจำนวนมากหรือรายการหมวดหมู่ยาว
ตาม Android Developers Blog, 2024 LazyRow ใช้สถาปัตยกรรม LazyList เดียวกับ LazyColumn รวมถึง LazyListState กลไกการนำกลับมาใช้ใหม่ผ่าน Pool และรองรับประเภทองค์ประกอบที่แตกต่างกัน ประสิทธิภาพสูงสุดทำได้ด้วยความสูงคงที่ขององค์ประกอบ
LazyRow รับพารามิเตอร์ modifier, state, contentPadding, reverseLayout, horizontalArrangement และ verticalAlignment เนื้อหาถูกกำหนดผ่านฟังก์ชัน DSL items และ item คล้ายกับ LazyColumn
@Composable
fun SimpleLazyRow() {
val items = (1..50).toList()
LazyRow(
modifier = Modifier.fillMaxWidth().height(100.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp),
contentPadding = PaddingValues(start = 16.dp, end = 16.dp)
) {
items(items) { item ->
Box(
modifier = Modifier.size(80.dp).background(Color.Gray)
) {
Text(text = "$item", modifier = Modifier.align(Alignment.Center))
}
}
}
}
horizontalArrangement จัดการการกระจายขององค์ประกอบตามแกนแนวนอนภายใน LazyRow ค่า Arrangement เดียวกับที่มีใน Row สามารถใช้ได้: Start, Center, End, SpaceBetween, SpaceEvenly, SpaceAround และ spacedBy ด้วยระยะห่างแบบกำหนดเอง
contentPadding เพิ่มระยะขอบที่ขอบของคอนเทนเนอร์ LazyRow แตกต่างจาก Modifier.padding ตรงที่ contentPadding จะถูกนำมาพิจารณาระหว่างการเลื่อน: องค์ประกอบแรกจะมีระยะขอบจากขอบซ้าย องค์ประกอบสุดท้ายจากขอบขวา ตาม Material Design Guidelines, 2025 contentPadding เป็นสิ่งจำเป็นสำหรับภาพหมุนและแกลเลอรีเพื่อให้องค์ประกอบแรกและสุดท้ายไม่ติดกับขอบหน้าจอ
verticalAlignment จัดแนวองค์ประกอบในแนวตั้งภายใน LazyRow โดยค่าเริ่มต้นใช้ Alignment.Top หากต้องการจัดกึ่งกลางองค์ประกอบที่มีความสูงต่างกัน ให้ใช้ Alignment.CenterVertically ซึ่งมีประโยชน์สำหรับภาพหมุนที่มีรูปภาพอัตราส่วนต่างกัน
| พารามิเตอร์ | คำอธิบาย | ค่าเริ่มต้น |
|---|---|---|
| horizontalArrangement | การกระจายแนวนอนขององค์ประกอบ | Arrangement.Start |
| contentPadding | ระยะขอบที่ขอบคอนเทนเนอร์ | PaddingValues(0.dp) |
| verticalAlignment | การจัดแนวตั้ง | Alignment.Top |
| reverseLayout | ลำดับองค์ประกอบย้อนกลับ | false |
| userScrollEnabled | เปิดใช้งานการเลื่อนโดยผู้ใช้ | true |
LazyListState สำหรับ LazyRow ทำงานเหมือนกับ LazyColumn: มันติดตามองค์ประกอบแรกที่มองเห็น ออฟเซ็ต และตำแหน่งการเลื่อนโดยรวม สถานะถูกสร้างขึ้นผ่าน rememberLazyListState() และส่งไปยังพารามิเตอร์ state
การควบคุมการเลื่อนแบบโปรแกรมของ LazyRow ทำด้วยวิธีการเดียวกัน: animateScrollToItem สำหรับแอนิเมชันราบรื่นและ scrollToItem สำหรับการเลื่อนทันที ทั้งสองถูกเรียกภายใน coroutine ซึ่งมีประโยชน์สำหรับภาพหมุนที่มีปุ่มเลื่อนซ้าย/ขวาหรือการเลื่อนอัตโนมัติ
ตาม Android Developers, 2024 LazyRow ยังรองรับ SnapFlingBehavior — พฤติกรรมการเลื่อนอย่างรวดเร็วที่หยุดที่องค์ประกอบที่ใกล้ที่สุดแทนที่จะหยุดระหว่างองค์ประกอบ ซึ่งสร้างเอฟเฟกต์การติดแน่นสำหรับภาพหมุนและแกลเลอรี
@Composable
fun CarouselWithSnap() {
val listState = rememberLazyListState()
val scope = rememberCoroutineScope()
val items = listOf("A", "B", "C", "D", "E")
Column {
LazyRow(
state = listState,
flingBehavior = SnapFlingBehavior(listState),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
items(items) { item ->
Card(modifier = Modifier.width(150.dp)) {
Text(text = item, modifier = Modifier.padding(16.dp))
}
}
}
Row(modifier = Modifier.fillMaxWidth()) {
Button(onClick = {
scope.launch {
listState.animateScrollToItem(0)
}
}) { Text("เพื่อเริ่มต้น") }
}
}
}
ตัวอย่างแรก — LazyRow สำหรับแกลเลอรีรูปภาพพร้อมตัวอย่าง แต่ละองค์ประกอบคือ Box ที่มีรูปภาพและคำอธิบายภาพ LazyRow จัดการรูปภาพหลายสิบและหลายร้อยรูปได้อย่างมีประสิทธิภาพ โดยโหลดเฉพาะรูปภาพที่มองเห็น
@Composable
fun ImageGallery(images: List<String>) {
LazyRow(
contentPadding = PaddingValues(start = 16.dp, end = 16.dp),
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
items(images, key = { it }) { url ->
AsyncImage(
model = url,
contentDescription = "Image",
modifier = Modifier.size(120.dp)
)
}
}
}
ตัวอย่างที่สอง — LazyRow สำหรับรายการหมวดหมู่พร้อมไอคอน หมวดหมู่จะแสดงเป็นชิปและผู้ใช้สามารถเลื่อนแนวนอนได้ LazyRow ที่มี spacedBy และ contentPadding สร้างระยะห่างระหว่างหมวดหมู่และที่ขอบ
@Composable
fun CategoryChips(categories: List<String>) {
LazyRow(
contentPadding = PaddingValues(horizontal = 16.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
items(categories, key = { it }) { category ->
AssistChip(
onClick = {},
label = { Text(category) }
)
}
}
}
การเลือกระหว่าง LazyRow และ Row ขึ้นอยู่กับจำนวนองค์ประกอบ Row เหมาะสำหรับ 5–10 องค์ประกอบที่มองเห็นได้เสมอบนหน้าจอ LazyRow จำเป็นเมื่อมีองค์ประกอบจำนวนมากหรือจำนวนองค์ประกอบเป็นแบบไดนามิก
Row แสดงผลองค์ประกอบทั้งหมดพร้อมกัน ทำให้เกิดความล่าช้าเมื่อมีองค์ประกอบจำนวนมาก LazyRow แสดงผลเฉพาะองค์ประกอบที่มองเห็น ทำให้เป็นที่นิยมสำหรับรายการที่เลื่อนได้ ตาม Android Developers Blog, 2024 เกณฑ์อยู่ที่ประมาณ 10 องค์ประกอบ: หากมีองค์ประกอบมากกว่านั้น ให้ใช้ LazyRow
LazyRow ยังรองรับแอนิเมชัน SnapFlingBehavior และการจัดกลุ่มผ่านตัวคั่น ทำให้มีความยืดหยุ่นมากขึ้นสำหรับอินเทอร์เฟซที่ซับซ้อน Row เรียบง่ายกว่าและไม่ต้องการ LazyListState แต่ไม่ได้ปรับให้เหมาะสมสำหรับรายการยาว
คำถามที่พบบ่อย
LazyRow เลื่อนแนวนอนและจัดวางองค์ประกอบจากซ้ายไปขวา ในขณะที่ LazyColumn เลื่อนแนวตั้งจากบนลงล่าง ทั้งคู่ใช้หลักการโหลดแบบขี้เกียจ LazyListState และฟังก์ชัน DSL items เหมือนกัน
ส่ง SnapFlingBehavior(listState) ไปยังพารามิเตอร์ flingBehavior ของ LazyRow SnapFlingBehavior บังคับให้ LazyRow หยุดที่องค์ประกอบที่ใกล้ที่สุดแทนที่จะหยุดระหว่างองค์ประกอบ สร้างเอฟเฟกต์การติดแน่นสำหรับภาพหมุน
ติดตามองค์ประกอบสุดท้ายที่มองเห็นผ่าน LazyListState.layoutInfo และโหลดข้อมูลใหม่เมื่อองค์ประกอบสุดท้ายใกล้ถึงจุดสิ้นสุดของรายการ สำหรับการเลื่อนแบบวนซ้ำ ให้ใช้การใช้งานแบบกำหนดเองพร้อมการทำสำเนาองค์ประกอบ
ได้ LazyRow สามารถซ้อนภายใน LazyColumn ได้ นี่เป็นรูปแบบมาตรฐานสำหรับสร้างหน้าที่ซับซ้อนด้วยภาพหมุนแนวนอนภายในรายการแนวตั้ง แต่ละ LazyRow ต้องมีความสูงคงที่เพื่อการทำงานที่ถูกต้อง
ใช้ LazyListState.layoutInfo.visibleItemsInfo และเปรียบเทียบดัชนีขององค์ประกอบสุดท้ายที่มองเห็นกับจำนวนทั้งหมดลบหนึ่ง เมื่อค่าเหล่านี้ตรงกัน LazyRow อยู่ที่จุดสิ้นสุดของรายการ
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม