SwipeToDismissBox
bileşeni, kullanıcının bir öğeyi sola veya sağa kaydırarak reddetmesine ya da güncellemesine olanak tanır.
API yüzeyi
Kaydırma hareketleriyle tetiklenen işlemleri uygulamak için SwipeToDismissBox
bileşenini kullanın. Temel parametreler şunlardır:
state
: Kaydırma öğesindeki hesaplamalar tarafından üretilen değeri depolamak için oluşturulanSwipeToDismissBoxState
durumu. Bu değer oluşturulduğunda etkinlikleri tetikler.backgroundContent
: Öğe içeriğinin arkasında gösterilen ve içerik kaydırıldığında ortaya çıkan özelleştirilebilir bir composable.
Temel örnek: Kaydırmayla güncelleme veya reddetmek
Bu örnekteki snippet'ler, başlangıçtan sona doğru kaydırıldığında öğeyi güncelleyen veya sondan başa doğru kaydırıldığında öğeyi kapatan bir kaydırma uygulaması göstermektedir.
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.") } ) } }
Kodla ilgili önemli noktalar
swipeToDismissBoxState
, bileşen durumunu yönetir. Öğeyle etkileşim sona erdiğindeconfirmValueChange
geri çağırma işlevini tetikler. Geri çağırma gövdesi, olası farklı işlemleri yönetir. Geri çağırma işlevi, bileşene kapatma animasyonu gösterip göstermeyeceğini belirten bir boole değeri döndürür. Bu durumda:- Öğe baştan sona kaydırılırsa geçerli
todoItem
değerini ileterekonToggleDone
lambda işlevini çağırır. Bu, yapılacaklar öğesinin güncellenmesine karşılık gelir. - Öğe uçtan uca kaydırılırsa mevcut
todoItem
değerini ileterekonRemove
lambda işlevini çağırır. Bu işlem, yapılacaklar listesindeki öğenin silinmesine karşılık gelir. it != StartToEnd
: Bu satır, kaydırma yönüStartToEnd
değilsetrue
, aksi takdirdefalse
değerini döndürür.false
döndürmek, "açma/kapatma işlemi tamamlandı" kaydırma işleminden sonraSwipeToDismissBox
'ın hemen kaybolmasını önler ve görsel bir onay veya animasyon sağlar.
- Öğe baştan sona kaydırılırsa geçerli
SwipeToDismissBox
, her öğede yatay kaydırma etkileşimlerini etkinleştirir. Dinlenme durumunda, bileşenin iç içeriğini gösterir ancak kullanıcı kaydırmaya başladığında içerik kaldırılır vebackgroundContent
simgesi gösterilir. Hem normal içerik hem debackgroundContent
, kendilerini oluşturmak için üst kapsayıcının tüm kısıtlamalarını alır.content
,backgroundContent
'un üzerine çizilir. Bu durumda:backgroundContent
,SwipeToDismissBoxValue
'ye dayalı bir arka plan rengine sahipIcon
olarak uygulanır:Blue
StartToEnd
kaydırırken: yapılacaklar listesindeki bir öğeyi etkinleştirme veya devre dışı bırakma.Red
EndToStart
kaydırırken: yapılacaklar listesindeki bir öğeyi silme.Settled
için arka planda hiçbir şey gösterilmez. Öğe kaydırıldığında arka planda hiçbir şey gösterilmez.- Benzer şekilde, gösterilen
Icon
, kaydırma yönüne uyar: StartToEnd
, yapılacaklar listesindeki öğe tamamlandığındaCheckBox
simgesi, tamamlanmadığında iseCheckBoxOutlineBlank
simgesi gösterir.EndToStart
,Delete
simgesi gösterir.
@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() ) } } }
Kodla ilgili önemli noktalar
mutableStateListOf(...)
,TodoItem
nesnesi barındırabilen gözlemlenebilir bir liste oluşturur. Bu listeye bir öğe eklendiğinde veya listeden kaldırıldığında, Oluştur, kullanıcı arayüzünün bu öğeye bağlı olan bölümlerini yeniden oluşturur.mutableStateListOf()
içinde, dörtTodoItem
nesnesi ilgili açıklamalarıyla başlatılır: "Faturaları öde", "Alışveriş yap", "Spor salonuna git" ve "Akşam yemeği ye".
LazyColumn
,todoItems
öğelerinin dikey olarak kaydırılan bir listesini görüntüler.onToggleDone = { todoItem -> ... }
, kullanıcı bir nesneyi bitti olarak işaretlediğindeTodoListItem
içinden çağrılan bir geri çağırma işlevidir.todoItem
öğesininisItemDone
özelliğini günceller.todoItems
birmutableStateListOf
olduğundan bu değişiklik, kullanıcı arayüzünü güncelleyerek yeniden birleştirme işlemini tetikler.onRemove = { todoItem -> ... }
, kullanıcı öğeyi kaldırdığında tetiklenen bir geri çağırma işlevidir. Belirli birtodoItem
öğesinitodoItems
listesinden kaldırır. Bu işlem, yeniden derlemeye de neden olur ve öğe, görüntülenen listeden kaldırılır.- Her
TodoListItem
öğesine biranimateItem
değiştirici uygulanır. Böylece, öğe kapatıldığında değiştiricininplacementSpec
işlevi çağrılır. Bu işlem, öğenin kaldırılmasının yanı sıra listedeki diğer öğelerin yeniden sıralanmasını animasyonlu olarak gösterir.
Sonuç
Aşağıdaki videoda, önceki snippet'lerdeki temel kaydırarak kapatma işlevi gösterilmektedir:
Örnek kodun tamamı için GitHub kaynak dosyasına bakın.
İleri seviye örnek: Kaydırma sırasında arka plan renginin animasyonu
Aşağıdaki snippet'lerde, öğenin arka plan renginin kaydırıldığında animasyonlu olarak gösterilmesi için konumsal eşiğin nasıl dahil edileceği gösterilmektedir.
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.") } ) } } }
Kodla ilgili önemli noktalar
drawBehind
, doğrudanIcon
kompozitinin içeriğinin arkasındaki tuvale çizer.drawRect()
, tuval üzerine bir dikdörtgen çizer ve çizim kapsamının tüm sınırlarını belirtilenColor
ile doldurur.
- Kaydırırken öğenin arka plan rengi
lerp
kullanılarak sorunsuz bir şekilde geçiş yapar.StartToEnd
'ten kaydırıldığında arka plan rengi açık griden maviye kademeli olarak değişir.EndToStart
'ten kaydırıldığında arka plan rengi açık griden kırmızıya kademeli olarak değişir.- Bir renkten diğerine geçiş miktarı
swipeToDismissBoxState.progress
tarafından belirlenir.
OutlinedCard
, liste öğeleri arasına ince bir görsel ayrım ekler.
@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() ) } } }
Kodla ilgili önemli noktalar
- Bu kodla ilgili önemli noktalar için önceki bir bölümdeki Önemli noktalar'a bakın. Bu bölümde, aynı kod snippet'i açıklanmaktadır.
Sonuç
Aşağıdaki videoda, animasyonlu arka plan rengiyle gelişmiş işlevler gösterilmektedir:
Örnek kodun tamamı için GitHub kaynak dosyasına bakın.