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şturulanSwipeToDismissBoxStatedurumu. 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ğindeconfirmValueChangegeri ç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
todoItemdeğerini ileterekonToggleDonelambda işlevini çağırır. Bu, yapılacaklar öğesinin güncellenmesine karşılık gelir. - Öğe uçtan uca kaydırılırsa mevcut
todoItemdeğerini ileterekonRemovelambda 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üStartToEnddeğilsetrue, aksi takdirdefalsedeğerini döndürür.falsedö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 vebackgroundContentsimgesi 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 sahipIconolarak uygulanır:BlueStartToEndkaydırırken: yapılacaklar listesindeki bir öğeyi etkinleştirme veya devre dışı bırakma.RedEndToStartkaydırırken: yapılacaklar listesindeki bir öğeyi silme.Settlediç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ığındaCheckBoxsimgesi, tamamlanmadığında iseCheckBoxOutlineBlanksimgesi gösterir.EndToStart,Deletesimgesi 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(...),TodoItemnesnesi 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örtTodoItemnesnesi 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ğindeTodoListItemiçinden çağrılan bir geri çağırma işlevidir.todoItemöğesininisItemDoneözelliğini günceller.todoItemsbirmutableStateListOfolduğ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öğesinitodoItemslistesinden 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 biranimateItemdeğiştirici uygulanır. Böylece, öğe kapatıldığında değiştiricininplacementSpeciş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ğrudanIconkompozitinin 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ı belirtilenColorile doldurur.
- Kaydırırken öğenin arka plan rengi
lerpkullanı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.progresstarafı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.