Le composant SwipeToDismissBox permet à un utilisateur d'ignorer ou de mettre à jour un élément en le balayant vers la gauche ou la droite.
Surface de l'API
Utilisez le composable SwipeToDismissBox pour implémenter des actions déclenchées par des gestes de balayage. Voici les principaux paramètres:
state: étatSwipeToDismissBoxStatecréé pour stocker la valeur générée par les calculs sur l'élément de balayage, qui déclenche des événements lorsqu'il est généré.backgroundContent: composable personnalisable affiché derrière le contenu de l'élément, qui s'affiche lorsque le contenu est balayé.
Exemple de base: Mise à jour ou refus en balayant l'écran
Les extraits de code de cet exemple montrent une implémentation de balayage qui met à jour l'élément lorsqu'il est balayé de gauche à droite ou le ferme lorsqu'il est balayé de droite à gauche.
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.") } ) } }
Points clés concernant le code
swipeToDismissBoxStategère l'état du composant. Il déclenche le rappelconfirmValueChangeune fois l'interaction avec l'élément terminée. Le corps du rappel gère les différentes actions possibles. Le rappel renvoie une valeur booléenne qui indique au composant s'il doit afficher une animation de fermeture. Dans ce cas :- Si l'élément est balayé de gauche à droite, il appelle le lambda 
onToggleDoneen transmettant letodoItemactuel. Cela correspond à la mise à jour de la tâche. - Si l'élément est balayé de la fin au début, il appelle le lambda 
onRemove, en transmettant letodoItemactuel. Cela correspond à la suppression de l'élément de la liste de tâches. it != StartToEnd: cette ligne renvoietruesi la direction du balayage n'est pasStartToEnd, etfalsedans le cas contraire. Le retour defalseempêche laSwipeToDismissBoxde disparaître immédiatement après un balayage "Activer/Désactiver", ce qui permet une confirmation ou une animation visuelle.
- Si l'élément est balayé de gauche à droite, il appelle le lambda 
 SwipeToDismissBoxpermet les interactions de balayage horizontal sur chaque élément. En mode veille, il affiche le contenu interne du composant, mais lorsqu'un utilisateur commence à balayer l'écran, le contenu est déplacé etbackgroundContents'affiche. Le contenu normal et lebackgroundContentobtiennent toutes les contraintes du conteneur parent pour s'afficher. Lecontentest dessiné au-dessus dubackgroundContent. Dans ce cas :backgroundContentest implémenté en tant queIconavec une couleur d'arrière-plan basée surSwipeToDismissBoxValue:Bluelors du balayageStartToEnd: activation/désactivation d'un élément de la liste de tâches.Redlorsque vous balayez l'écranEndToStart: suppression d'un élément de la liste de tâches.- Rien n'est affiché en arrière-plan pour 
Settled. Lorsque l'élément n'est pas balayé, rien n'est affiché en arrière-plan. - De même, le 
Iconaffiché s'adapte à la direction du balayage: StartToEndaffiche une icôneCheckBoxlorsque la tâche est terminée et une icôneCheckBoxOutlineBlanklorsqu'elle ne l'est pas.EndToStartaffiche une icôneDelete.
@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() ) } } }
Points clés concernant le code
mutableStateListOf(...)crée une liste observable pouvant contenir des objetsTodoItem. Lorsqu'un élément est ajouté ou supprimé de cette liste, Compose recompose les parties de l'UI qui en dépendent.- Dans 
mutableStateListOf(), quatre objetsTodoItemsont initialisés avec leurs descriptions respectives: "Payer les factures", "Acheter des produits alimentaires", "Aller à la salle de sport" et "Dîner". 
- Dans 
 LazyColumnaffiche une liste à défilement vertical detodoItems.onToggleDone = { todoItem -> ... }est une fonction de rappel appelée depuisTodoListItemlorsque l'utilisateur marque un objet comme terminé. Il met à jour la propriétéisItemDonedetodoItem. Étant donné quetodoItemsest unmutableStateListOf, cette modification déclenche une recomposition, ce qui met à jour l'UI.onRemove = { todoItem -> ... }est une fonction de rappel déclenchée lorsque l'utilisateur supprime l'élément. Il supprime l'todoItemspécifique de la listetodoItems. Une recomposition est également effectuée, et l'élément est supprimé de la liste affichée.- Un modificateur 
animateItemest appliqué à chaqueTodoListItemafin que leplacementSpecdu modificateur soit appelé lorsque l'élément a été ignoré. Cela anime la suppression de l'élément, ainsi que la réorganisation des autres éléments de la liste. 
Résultat
La vidéo suivante illustre la fonctionnalité de base de balayage pour ignorer des extraits précédents:
Pour obtenir l'exemple de code complet, consultez le fichier source GitHub.
Exemple avancé: animer la couleur d'arrière-plan lors d'un balayage
Les extraits de code suivants montrent comment intégrer un seuil de position pour animer la couleur d'arrière-plan d'un élément lors d'un balayage.
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.") } ) } } }
Points clés concernant le code
drawBehinddessine directement dans le canevas derrière le contenu du composableIcon.drawRect()dessine un rectangle sur le canevas et remplit l'ensemble des limites du champ d'application du dessin avec laColorspécifiée.
- Lorsque vous balayez l'écran, la couleur d'arrière-plan de l'élément passe en douceur à l'aide de 
lerp.- Pour un balayage à partir de 
StartToEnd, la couleur d'arrière-plan passe progressivement du gris clair au bleu. - Pour un balayage à partir de 
EndToStart, la couleur d'arrière-plan passe progressivement du gris clair au rouge. - La quantité de transition d'une couleur à l'autre est déterminée par 
swipeToDismissBoxState.progress. 
 - Pour un balayage à partir de 
 OutlinedCardajoute une séparation visuelle subtile entre les éléments de liste.
@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() ) } } }
Points clés concernant le code
- Pour en savoir plus sur ce code, consultez les points clés d'une section précédente, qui décrit un extrait de code identique.
 
Résultat
La vidéo suivante présente les fonctionnalités avancées avec une couleur d'arrière-plan animée:
Pour obtenir l'exemple de code complet, consultez le fichier source GitHub.