Hi everyone :wave: I'm running into a frustrating...
# compose-android
j
Hi everyone 👋 I'm running into a frustrating issue with
SwipeToDismissBox
and hope you can help me out. I’m implementing a pretty classic pattern: I have items in a
LazyColumn
, and users can swipe to dismiss an item. They also have a short time to undo the dismissal. I’ll add more details about my current implementation in the replies. Looking forward to any ideas or suggestions!
Copy code
@Composable
fun SwipeDismissTaskItem(
    modifier: Modifier = Modifier,
    isDone: Boolean = false,
    isVisible: Boolean = true,
    enter: EnterTransition = expandVertically(),
    exit: ExitTransition = shrinkVertically(),
    onStartToEnd: () -> Unit,
    onEndToStart: () -> Unit,
    background: @Composable (progress: Float, targetValue: SwipeToDismissBoxValue) -> Unit,
    content: @Composable (isDismissed: Boolean) -> Unit,
) {
    val dismissState = rememberSwipeToDismissBoxState()
    val isDismissed = dismissState.currentValue != SwipeToDismissBoxValue.Settled

    AnimatedVisibility(
        visible = isVisible,
        modifier = modifier,
        enter = enter,
        exit = exit
    ) {
        SwipeToDismissBox(
            modifier = modifier,
            state = dismissState,
            enableDismissFromStartToEnd = isDone,
            backgroundContent = { background(dismissState.progress, dismissState.targetValue) },
            content = { content(isDismissed) }
        )
    }

    LaunchedEffect(dismissState.currentValue) {
        when (dismissState.currentValue) {
            SwipeToDismissBoxValue.StartToEnd -> onStartToEnd()
            SwipeToDismissBoxValue.EndToStart -> onEndToStart()
            else -> Unit
        }
    }
}
Here’s the composable I’m using When the user swipes an item, I set
isVisible = false
in my ViewModel, so
AnimatedVisibility
hides it smoothly. After ~2 seconds, the item is removed from the list — that part works fine. The issue is when the user undoes the action: the item is visible again, but
dismissState
is still stuck in
EndToStart
, so it immediately triggers the swipe logic again. Things I tried : • Removing the item from the list directly instead of using
isVisible
, thinking that leaving the composition would reset the state… but nope,
dismissState
still remembers it. • Manually resetting the state with
snapTo(SwipeToDismissBoxValue.Settled)
, but that causes UI glitches. I would love to hear if someone has a clean way to reset the swipe state when an item comes back into the list
I found a fix that works for my use case. The issue came from the fact that
rememberSwipeToDismissBoxState()
uses
rememberSaveable
under the hood — so when the item re-enters the composition, the previous state is restored. That’s expected, but it wasn’t what I wanted in this case. What I ended up doing is creating a custom version of
rememberSwipeToDismissBoxState
that just uses
remember
instead. Since
remember
doesn’t survive if the composable is removed from the composition, this gave me exactly the behavior I wanted. I think it would be useful if
rememberSwipeToDismissBoxState
allowed passing a key (like
remember(key)
) to control when it should be reset. That would make this kind of use case easier to handle.