คอมโพเนนต์ SwipeToDismissBox ช่วยให้ผู้ใช้ปิดหรืออัปเดตรายการได้ด้วยการปัดไปทางซ้ายหรือขวา
แพลตฟอร์ม API
ใช้คอมโพสิเบิล SwipeToDismissBox เพื่อใช้การดำเนินการที่เรียกให้แสดงโดยท่าทางสัมผัสด้วยการปัด พารามิเตอร์หลักๆ มีดังนี้
state: สถานะSwipeToDismissBoxStateที่สร้างขึ้นเพื่อจัดเก็บค่าที่เกิดจากการคํานวณในรายการการปัด ซึ่งจะทริกเกอร์เหตุการณ์เมื่อสร้างขึ้นbackgroundContent: Composable ที่ปรับแต่งได้ซึ่งแสดงอยู่หลังรายการ เนื้อหาที่จะแสดงเมื่อมีการปัดเนื้อหา
ตัวอย่างพื้นฐาน: อัปเดตหรือปิดเมื่อปัด
ตัวอย่างนี้คือการใช้การปัดที่อัปเดตรายการเมื่อปัดจากต้นไปสิ้นสุด หรือปิดรายการเมื่อปัดจากสิ้นสุดไปต้น
data class TodoItem( val itemDescription: String, var isItemDone: Boolean = false )
@Composable fun TodoListItem( todoItem: TodoItem, onToggleDone: (TodoItem) -> Unit, onRemove: (TodoItem) -> Unit, modifier: Modifier = Modifier, ) { val swipeToDismissBoxState = rememberSwipeToDismissBoxState( confirmValueChange = { if (it == StartToEnd) onToggleDone(todoItem) else if (it == EndToStart) onRemove(todoItem) // Reset item when toggling done status it != StartToEnd } ) SwipeToDismissBox( state = swipeToDismissBoxState, modifier = modifier.fillMaxSize(), backgroundContent = { when (swipeToDismissBoxState.dismissDirection) { StartToEnd -> { Icon( if (todoItem.isItemDone) Icons.Default.CheckBox else Icons.Default.CheckBoxOutlineBlank, contentDescription = if (todoItem.isItemDone) "Done" else "Not done", modifier = Modifier .fillMaxSize() .background(Color.Blue) .wrapContentSize(Alignment.CenterStart) .padding(12.dp), tint = Color.White ) } EndToStart -> { Icon( imageVector = Icons.Default.Delete, contentDescription = "Remove item", modifier = Modifier .fillMaxSize() .background(Color.Red) .wrapContentSize(Alignment.CenterEnd) .padding(12.dp), tint = Color.White ) } Settled -> {} } } ) { ListItem( headlineContent = { Text(todoItem.itemDescription) }, supportingContent = { Text("swipe me to update or remove.") } ) } }
ประเด็นสำคัญเกี่ยวกับรหัส
swipeToDismissBoxStateจัดการสถานะคอมโพเนนต์ ซึ่งจะทริกเกอร์การเรียกกลับconfirmValueChangeเมื่อการโต้ตอบกับรายการเสร็จสิ้น เนื้อหาของคอลแบ็กจะจัดการการดำเนินการต่างๆ ที่เป็นไปได้ ฟังก์ชันการเรียกกลับจะแสดงผลเป็นค่าบูลีนซึ่งบอกคอมโพเนนต์ว่าควรแสดงภาพเคลื่อนไหวการปิดหรือไม่ ในกรณีนี้- หากปัดรายการจากต้นจนจบ ระบบจะเรียกใช้ 
onToggleDonelambda โดยส่งtodoItemปัจจุบัน ซึ่งสอดคล้องกับการอัปเดตรายการสิ่งที่ต้องทำ - หากปัดรายการจากท้ายไปต้น ระบบจะเรียกใช้ Lambda 
onRemoveโดยส่งtodoItemปัจจุบัน ซึ่งสอดคล้องกับการลบรายการที่ต้องทำ it != StartToEnd: บรรทัดนี้จะแสดงผลtrueหากทิศทางการปัดไม่ใช่StartToEndและแสดงผลfalseในกรณีอื่นๆfalseที่กลับมาจะป้องกันไม่ให้SwipeToDismissBoxหายไปทันทีหลังจากการปัด "สลับเสร็จแล้ว" ซึ่งช่วยให้เห็นภาพยืนยันหรือภาพเคลื่อนไหว
- หากปัดรายการจากต้นจนจบ ระบบจะเรียกใช้ 
 SwipeToDismissBoxเปิดใช้การโต้ตอบด้วยการปัดแนวนอนในแต่ละรายการ เมื่ออยู่ในสถานะ "พัก" ไอคอนจะแสดงเนื้อหาภายในของคอมโพเนนต์ แต่เมื่อผู้ใช้เริ่มปัด เนื้อหาจะเลื่อนออกไปและbackgroundContentจะปรากฏขึ้น ทั้งเนื้อหาปกติและbackgroundContentจะได้รับข้อจำกัดทั้งหมดของคอนเทนเนอร์หลักเพื่อแสดงผลcontentวาดอยู่ด้านบนของbackgroundContentในกรณีนี้backgroundContentติดตั้งใช้งานเป็นIconที่มีสีพื้นหลังตามSwipeToDismissBoxValueดังนี้Blueเมื่อปัดStartToEnd- สลับรายการสิ่งที่ต้องทำRedเมื่อปัดEndToStart- ลบรายการสิ่งที่ต้องทํา- ไม่มีสิ่งใดแสดงในเบื้องหลังสำหรับ 
Settled— เมื่อไม่ได้ปัดรายการ ระบบจะไม่แสดงสิ่งใดในเบื้องหลัง - ในทำนองเดียวกัน 
Iconที่แสดงจะปรับตามทิศทางการปัด StartToEndจะแสดงไอคอนCheckBoxเมื่องานในรายการสิ่งที่ต้องทำเสร็จแล้ว และไอคอนCheckBoxOutlineBlankเมื่องานยังไม่เสร็จEndToStartแสดงไอคอนDelete
@Composable private fun SwipeItemExample() { val todoItems = remember { mutableStateListOf( TodoItem("Pay bills"), TodoItem("Buy groceries"), TodoItem("Go to gym"), TodoItem("Get dinner") ) } LazyColumn { items( items = todoItems, key = { it.itemDescription } ) { todoItem -> TodoListItem( todoItem = todoItem, onToggleDone = { todoItem -> todoItem.isItemDone = !todoItem.isItemDone }, onRemove = { todoItem -> todoItems -= todoItem }, modifier = Modifier.animateItem() ) } } }
ประเด็นสำคัญเกี่ยวกับรหัส
mutableStateListOf(...)สร้างลิสต์ที่สังเกตได้ซึ่งเก็บออบเจ็กต์TodoItemได้ เมื่อมีการเพิ่มหรือนำรายการออกจากรายการนี้ คอมโพซจะจัดเรียงองค์ประกอบ UI ที่ขึ้นอยู่กับรายการนั้นใหม่- ภายใน 
mutableStateListOf()ระบบจะเริ่มต้นออบเจ็กต์TodoItem4 รายการพร้อมคำอธิบายที่เกี่ยวข้อง ได้แก่ "จ่ายบิล" "ซื้อของใช้ทั่วไป" "ไปฟิตเนส" และ "ทานอาหารเย็น" 
- ภายใน 
 LazyColumnแสดงรายการtodoItemsแบบเลื่อนในแนวตั้งonToggleDone = { todoItem -> ... }คือฟังก์ชันการเรียกกลับที่เรียกจากภายในTodoListItemเมื่อผู้ใช้ทำเครื่องหมายวัตถุว่าเสร็จแล้ว โดยจะอัปเดตพร็อพเพอร์ตี้isItemDoneของtodoItemเนื่องจากtodoItemsเป็นmutableStateListOfการเปลี่ยนแปลงนี้จึงทริกเกอร์การจัดองค์ประกอบใหม่เพื่ออัปเดต UIonRemove = { todoItem -> ... }คือฟังก์ชัน Callback ที่ทริกเกอร์เมื่อผู้ใช้นำรายการออก ซึ่งจะนำtodoItemที่เฉพาะเจาะจงออกจากรายการtodoItemsซึ่งจะทําให้เกิดการจัดองค์ประกอบใหม่ด้วย และระบบจะนำรายการออกจากรายการที่แสดง- ระบบจะใช้ตัวแก้ไข 
animateItemกับTodoListItemแต่ละรายการเพื่อให้ระบบเรียกplacementSpecของตัวแก้ไขเมื่อมีการปิดรายการ ซึ่งจะแสดงภาพการนำรายการออก รวมถึงการจัดเรียงรายการอื่นๆ ในรายการใหม่ 
ผลลัพธ์
วิดีโอต่อไปนี้แสดงฟังก์ชันการปัดเพื่อปิดพื้นฐานจากตัวอย่างข้อมูลก่อนหน้า
ดูโค้ดตัวอย่างแบบเต็มได้ที่ไฟล์ซอร์ส GitHub
ตัวอย่างขั้นสูง: แสดงสีพื้นหลังเป็นภาพเคลื่อนไหวเมื่อปัด
ข้อมูลโค้ดต่อไปนี้แสดงวิธีใช้เกณฑ์ตำแหน่งเพื่อทำให้สีพื้นหลังของรายการเคลื่อนไหวเมื่อปัด
data class TodoItem( val itemDescription: String, var isItemDone: Boolean = false )
@Composable fun TodoListItemWithAnimation( todoItem: TodoItem, onToggleDone: (TodoItem) -> Unit, onRemove: (TodoItem) -> Unit, modifier: Modifier = Modifier, ) { val swipeToDismissBoxState = rememberSwipeToDismissBoxState( confirmValueChange = { if (it == StartToEnd) onToggleDone(todoItem) else if (it == EndToStart) onRemove(todoItem) // Reset item when toggling done status it != StartToEnd } ) SwipeToDismissBox( state = swipeToDismissBoxState, modifier = modifier.fillMaxSize(), backgroundContent = { when (swipeToDismissBoxState.dismissDirection) { StartToEnd -> { Icon( if (todoItem.isItemDone) Icons.Default.CheckBox else Icons.Default.CheckBoxOutlineBlank, contentDescription = if (todoItem.isItemDone) "Done" else "Not done", modifier = Modifier .fillMaxSize() .drawBehind { drawRect(lerp(Color.LightGray, Color.Blue, swipeToDismissBoxState.progress)) } .wrapContentSize(Alignment.CenterStart) .padding(12.dp), tint = Color.White ) } EndToStart -> { Icon( imageVector = Icons.Default.Delete, contentDescription = "Remove item", modifier = Modifier .fillMaxSize() .background(lerp(Color.LightGray, Color.Red, swipeToDismissBoxState.progress)) .wrapContentSize(Alignment.CenterEnd) .padding(12.dp), tint = Color.White ) } Settled -> {} } } ) { OutlinedCard(shape = RectangleShape) { ListItem( headlineContent = { Text(todoItem.itemDescription) }, supportingContent = { Text("swipe me to update or remove.") } ) } } }
ประเด็นสำคัญเกี่ยวกับรหัส
drawBehindจะวาดลงในผืนผ้าใบโดยตรงหลังเนื้อหาของIconcomposabledrawRect()วาดสี่เหลี่ยมผืนผ้าบนผืนผ้าและเติมColorที่ระบุไว้ทั่วทั้งขอบเขตการวาด
- เมื่อปัด พื้นหลังของรายการจะเปลี่ยนอย่างราบรื่นโดยใช้
lerp- สำหรับการปัดจาก 
StartToEndสีพื้นหลังจะค่อยๆ เปลี่ยนจากสีเทาอ่อนเป็นสีน้ำเงิน - สำหรับการปัดจาก 
EndToStartสีพื้นหลังจะค่อยๆ เปลี่ยนจากสีเทาอ่อนเป็นสีแดง - ปริมาณการเปลี่ยนจากสีหนึ่งไปยังอีกสีหนึ่งจะกำหนดโดย
swipeToDismissBoxState.progress 
 - สำหรับการปัดจาก 
 OutlinedCardเพิ่มการแยกภาพอย่างละเอียดระหว่างรายการในลิสต์
@Composable private fun SwipeItemWithAnimationExample() { val todoItems = remember { mutableStateListOf( TodoItem("Pay bills"), TodoItem("Buy groceries"), TodoItem("Go to gym"), TodoItem("Get dinner") ) } LazyColumn { items( items = todoItems, key = { it.itemDescription } ) { todoItem -> TodoListItemWithAnimation( todoItem = todoItem, onToggleDone = { todoItem -> todoItem.isItemDone = !todoItem.isItemDone }, onRemove = { todoItem -> todoItems -= todoItem }, modifier = Modifier.animateItem() ) } } }
ประเด็นสำคัญเกี่ยวกับรหัส
- ดูประเด็นสําคัญเกี่ยวกับโค้ดนี้ได้ที่ประเด็นสําคัญจากส่วนก่อนหน้า ซึ่งอธิบายข้อมูลโค้ดที่เหมือนกัน
 
ผลลัพธ์
วิดีโอต่อไปนี้แสดงฟังก์ชันขั้นสูงที่มีพื้นหลังเคลื่อนไหว
ดูโค้ดตัวอย่างแบบเต็มได้ที่ไฟล์ซอร์ส GitHub