SwipeToDismissBox bileşeni, kullanıcıların bir öğeyi sola veya sağa kaydırarak kapatmasına ya da güncellemesine olanak tanır.
API yüzeyi
Kaydırma hareketleriyle tetiklenen işlemleri uygulamak için SwipeToDismissBox composable'ını kullanın. Temel parametreler şunlardır:
state: Kaydırma öğesi üzerinde yapılan hesaplamalarla üretilen değeri depolamak için oluşturulanSwipeToDismissBoxStatedurumu. Bu durum, üretildiğinde 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ırarak güncelleme veya kapatma
Bu örnekteki snippet'ler, baştan sona kaydırıldığında öğeyi güncelleyen veya sondan başa kaydırıldığında öğeyi kapatan bir kaydırma uygulamasını gösterir.
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( painter = rememberVectorPainter(if (todoItem.isItemDone) AppIcons.CheckBox else AppIcons.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( painter = rememberVectorPainter(AppIcons.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
- Bileşen durumunu
swipeToDismissBoxStateyönetir. Öğeyle etkileşim tamamlandığındaconfirmValueChangegeri çağırma işlevini tetikler. Geri çağırma gövdesi, farklı olası işlemleri işler. Geri çağırma, bileşene kapatma animasyonu gösterip göstermemesi gerektiğ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'yı çağırır. Bu, yapılacaklar öğesini güncellemeye karşılık gelir. - Öğe, sondan başa doğru kaydırılırsa geçerli
todoItemdeğerini ileterekonRemovelambda'yı çağırır. Bu, yapılacaklar öğesini silmeye 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, "tamamlandı olarak işaretle" kaydırma işleminden sonraSwipeToDismissBoxöğesinin hemen kaybolmasını önleyerek görsel bir onay veya animasyon gösterilmesine olanak tanır.
- Öğe baştan sona kaydırılırsa geçerli
SwipeToDismissBox, her öğede yatay kaydırma etkileşimlerini etkinleştirir. Bekleme durumunda bileşenin iç içeriğini gösterir ancak kullanıcı kaydırmaya başladığında içerik kaldırılır vebackgroundContentgörünür. 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öğesinin üzerine çizilir. Bu durumda:backgroundContent, arka plan rengiSwipeToDismissBoxValue'ye dayalı birIconolarak uygulanır:Blue,StartToEndkaydırıldığında yapılacaklar öğesini açıp kapatır.Red,EndToStartkaydırıldığında yapılacaklar listesindeki bir öğeyi siliyor.Settlediçin arka planda hiçbir şey gösterilmez. Öğe kaydırılmadığında arka planda hiçbir şey gösterilmez.- Benzer şekilde, gösterilen
Iconkaydırma yönüne uyum sağlar: StartToEnd, yapılacaklar listesindeki öğe tamamlandığındaCheckBoxsimgesini, tamamlanmadığında iseCheckBoxOutlineBlanksimgesini gösterir.EndToStart,Deletesimgesini gösterir.
@Composable 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(...),TodoItemnesnelerini barındırabilen gözlemlenebilir bir liste oluşturur. Bu listeye bir öğe eklendiğinde veya listeden bir öğe kaldırıldığında Compose, kullanıcı arayüzünün bu listeye bağlı olan kısımlarını yeniden oluşturur.mutableStateListOf()içinde, dörtTodoItemnesnesi kendi açıklamalarıyla başlatılır: "Faturaları öde", "Market alışverişi yap", "Spor salonuna git" ve "Akşam yemeği ye".
LazyColumn, dikey olarak kaydırılan birtodoItemslistesi gösterir.onToggleDone = { todoItem -> ... }, kullanıcı bir nesneyi tamamlandı 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, yeniden oluşturmayı tetikleyerek kullanıcı arayüzünü günceller.onRemove = { todoItem -> ... }, kullanıcı öğeyi kaldırdığında tetiklenen bir geri çağırma işlevidir. Belirli birtodoItemöğesinitodoItemslistesinden kaldırır. Bu işlem de yeniden oluşturmaya neden olur ve öğe, görüntülenen listeden kaldırılır.- Öğe kapatıldığında değiştiricinin
placementSpecişlevi çağrılacak şekilde herTodoListItemöğesine biranimateItemdeğiştirici uygulanır. Bu işlem, öğenin kaldırılmasını ve listedeki diğer öğelerin yeniden sıralanmasını animasyonlu olarak gösterir.
Sonuç
Aşağıdaki videoda, önceki snippet'lerde yer alan temel kaydırarak kapatma işlevi gösterilmektedir:
Örnek kodun tamamı için GitHub kaynak dosyasına bakın.
İleri düzey örnek: Kaydırma sırasında arka plan rengini canlandırma
Aşağıdaki snippet'lerde, kaydırma sırasında bir öğenin arka plan rengini canlandırmak 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( painter = rememberVectorPainter(if (todoItem.isItemDone) AppIcons.CheckBox else AppIcons.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( painter = rememberVectorPainter(AppIcons.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ğrudanIconcomposable'ının içeriğinin arkasındaki tuvale çizim yapar.drawRect(), tuval üzerine bir dikdörtgen çizer ve çizim kapsamının tüm sınırlarını belirtilenColorile doldurur.
- Kaydırma sırasında öğenin arka plan rengi
lerpkullanılarak sorunsuz bir şekilde geçiş yapar.StartToEndyönünden kaydırıldığında arka plan rengi kademeli olarak açık gri renkten maviye döner.EndToStarttarafından kaydırıldığında arka plan rengi kademeli olarak açık griden kırmızıya değişir.- Bir renkten diğerine geçiş miktarı
swipeToDismissBoxState.progressile belirlenir.
OutlinedCard, liste öğeleri arasında hafif 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ümde yer alan ve aynı kod snippet'ini açıklayan Önemli noktalar bölümüne bakın.
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.