Skip to content

Instantly share code, notes, and snippets.

@zenyagami
Created July 24, 2024 14:56
Show Gist options
  • Save zenyagami/10eddf46bec782545b2a8e0543ee66e2 to your computer and use it in GitHub Desktop.
Save zenyagami/10eddf46bec782545b2a8e0543ee66e2 to your computer and use it in GitHub Desktop.
SwipeToDeleteCompose for material3
@Composable
fun <T> SwipeToDeleteContainer(
item: T,
onDelete: (T) -> Unit,
animationDuration: Int = 500,
content: @Composable (T) -> Unit,
) {
var isRemoved by remember { mutableStateOf(false) }
val state = rememberSwipeToDismissBoxState(
confirmValueChange = { value ->
return@rememberSwipeToDismissBoxState when (value) {
SwipeToDismissBoxValue.StartToEnd,
SwipeToDismissBoxValue.EndToStart,
-> true
SwipeToDismissBoxValue.Settled -> false
}.also { isRemoved = it }
}
)
LaunchedEffect(key1 = isRemoved) {
if (isRemoved) {
delay(animationDuration.toLong())
onDelete(item)
}
}
AnimatedVisibility(
visible = !isRemoved,
exit = shrinkVertically(
animationSpec = tween(durationMillis = animationDuration),
shrinkTowards = Alignment.Top
) + fadeOut()
) {
SwipeToDismissBox(
state = state,
backgroundContent = {
DeleteBackground(swipeDismissState = state)
},
enableDismissFromEndToStart = true,
enableDismissFromStartToEnd = true,
content = { content(item) }
)
}
}
@Composable
fun DeleteBackground(swipeDismissState: SwipeToDismissBoxState) {
val color = if (swipeDismissState.dismissDirection == SwipeToDismissBoxValue.EndToStart) {
MaterialTheme.colorScheme.error
} else Color.Transparent
Box(
modifier = Modifier
.fillMaxSize()
.background(color)
.padding(16.dp),
contentAlignment = Alignment.CenterEnd
) {
Icon(
imageVector = Icons.Default.Delete,
contentDescription = null,
tint = Color.White
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment