Komponen SwipeToDismissBox memungkinkan pengguna menutup atau memperbarui
item dengan menggesernya ke kiri atau kanan.
Platform API
Gunakan composable SwipeToDismissBox untuk menerapkan tindakan yang dipicu
oleh gestur geser. Parameter utamanya meliputi:
state: StatusSwipeToDismissBoxStateyang dibuat untuk menyimpan nilai yang dihasilkan oleh penghitungan pada item geser, yang memicu peristiwa saat dibuat.backgroundContent: Composable yang dapat disesuaikan yang ditampilkan di belakang konten item yang ditampilkan saat konten digeser.
Contoh dasar: Memperbarui atau menutup dengan menggeser
Cuplikan dalam contoh ini menunjukkan implementasi geser yang memperbarui item saat digeser dari awal hingga akhir, atau menutup item saat digeser dari akhir ke awal.
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.") } ) } }
Poin-poin penting tentang kode
swipeToDismissBoxStatemengelola status komponen. Tindakan ini memicu callbackconfirmValueChangesetelah interaksi dengan item selesai. Isi callback menangani berbagai kemungkinan tindakan. Callback menampilkan boolean yang memberi tahu komponen apakah harus menampilkan animasi penonaktifan. Dalam hal ini:- Jika item digeser dari awal hingga akhir, item tersebut akan memanggil lambda 
onToggleDone, yang meneruskantodoItemsaat ini. Hal ini sesuai dengan memperbarui item daftar tugas. - Jika item digeser dari akhir ke awal, item tersebut akan memanggil lambda 
onRemove, yang meneruskantodoItemsaat ini. Tindakan ini sesuai dengan penghapusan item daftar tugas. it != StartToEnd: Baris ini menampilkantruejika arah geser bukanStartToEnd, danfalsejika sebaliknya. MenampilkanfalsemencegahSwipeToDismissBoxlangsung menghilang setelah geser "tombol selesai", sehingga memungkinkan konfirmasi atau animasi visual.
- Jika item digeser dari awal hingga akhir, item tersebut akan memanggil lambda 
 SwipeToDismissBoxmemungkinkan interaksi geser horizontal pada setiap item. Dalam istirahat, komponen ini menampilkan konten bagian dalam komponen, tetapi saat pengguna mulai menggeser, konten akan dipindahkan danbackgroundContentakan muncul. Konten normal danbackgroundContentmendapatkan batasan penuh penampung induk untuk merendernya.contentdigambar di atasbackgroundContent. Dalam hal ini:backgroundContentditerapkan sebagaiIcondengan warna latar belakang berdasarkanSwipeToDismissBoxValue:Bluesaat menggeserStartToEnd— mengalihkan item daftar tugas.Redsaat menggeserEndToStart— menghapus item daftar tugas.- Tidak ada yang ditampilkan di latar belakang untuk 
Settled— saat item tidak digeser, tidak ada yang ditampilkan di latar belakang. - Demikian pula, 
Iconyang ditampilkan akan menyesuaikan dengan arah geser: StartToEndmenampilkan ikonCheckBoxsaat item daftar tugas selesai dan ikonCheckBoxOutlineBlanksaat belum selesai.EndToStartmenampilkan ikonDelete.
@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() ) } } }
Poin-poin penting tentang kode
mutableStateListOf(...)membuat daftar yang dapat diamati yang dapat menyimpan objekTodoItem. Saat item ditambahkan atau dihapus dari daftar ini, Compose akan merekomposisi bagian UI yang bergantung padanya.- Di dalam 
mutableStateListOf(), empat objekTodoItemdiinisialisasi dengan deskripsi masing-masing: "Bayar tagihan", "Beli bahan makanan", "Pergi ke gym", dan "Beli makan malam". 
- Di dalam 
 LazyColumnmenampilkan daftartodoItemsyang di-scroll secara vertikal.onToggleDone = { todoItem -> ... }adalah fungsi callback yang dipanggil dari dalamTodoListItemsaat pengguna menandai objek sebagai selesai. Class ini memperbarui propertiisItemDonedaritodoItem. KarenatodoItemsadalahmutableStateListOf, perubahan ini memicu rekomposisi, yang mengupdate UI.onRemove = { todoItem -> ... }adalah fungsi callback yang dipicu saat pengguna menghapus item. Tindakan ini akan menghapustodoItemtertentu dari daftartodoItems. Tindakan ini juga menyebabkan rekomposisi, dan item akan dihapus dari daftar yang ditampilkan.- Pengubah 
animateItemditerapkan ke setiapTodoListItemsehinggaplacementSpecpengubah dipanggil saat item ditutup. Tindakan ini akan menganimasikan penghapusan item, serta pengurutan ulang item lain dalam daftar. 
Hasil
Video berikut menunjukkan fungsi geser untuk menutup dasar dari cuplikan sebelumnya:
Lihat file sumber GitHub untuk mengetahui kode contoh lengkap.
Contoh lanjutan: Menganimasikan warna latar belakang saat menggeser
Cuplikan berikut menunjukkan cara menggabungkan nilai minimum posisi untuk menganimasikan warna latar belakang item saat menggeser.
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.") } ) } } }
Poin-poin penting tentang kode
drawBehindmenggambar langsung ke kanvas di belakang konten composableIcon.drawRect()menggambar persegi panjang di kanvas dan mengisi seluruh batas cakupan gambar denganColoryang ditentukan.
- Saat menggeser, warna latar belakang item akan bertransisi dengan lancar menggunakan
lerp.- Untuk geser dari 
StartToEnd, warna latar belakang secara bertahap berubah dari abu-abu terang menjadi biru. - Untuk geser dari 
EndToStart, warna latar belakang secara bertahap berubah dari abu-abu terang menjadi merah. - Jumlah transisi dari satu warna ke warna berikutnya ditentukan oleh
swipeToDismissBoxState.progress. 
 - Untuk geser dari 
 OutlinedCardmenambahkan pemisahan visual yang halus di antara item daftar.
@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() ) } } }
Poin-poin penting tentang kode
- Untuk mengetahui poin-poin penting tentang kode ini, lihat Poin-poin penting dari bagian sebelumnya, yang menjelaskan cuplikan kode yang identik.
 
Hasil
Video berikut menunjukkan fungsi lanjutan dengan warna latar belakang animasikan:
Lihat file sumber GitHub untuk mengetahui kode contoh lengkap.