Skip to content

Instantly share code, notes, and snippets.

@bmc08gt
Last active December 15, 2023 03:40
import androidx.compose.animation.*
import androidx.compose.animation.core.tween
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.onCommit
import androidx.compose.ui.Modifier
@OptIn(ExperimentalAnimationApi::class, ExperimentalMaterialApi::class)
@Composable
fun <T> AnimatedSwipeDismiss(
modifier: Modifier = Modifier,
item: T,
background: @Composable (isDismissed: Boolean) -> Unit,
content: @Composable (isDismissed: Boolean) -> Unit,
directions: Set<DismissDirection> = setOf(DismissDirection.EndToStart),
enter: EnterTransition = expandVertically(),
exit: ExitTransition = shrinkVertically(
animSpec = tween(
durationMillis = 500,
)
),
onDismiss: (T) -> Unit
) {
val dismissState = rememberDismissState()
val isDismissed = dismissState.isDismissed(DismissDirection.EndToStart)
onCommit(dismissState.value) {
if (dismissState.value == DismissValue.DismissedToStart) {
onDismiss(item)
}
}
AnimatedVisibility(
modifier = modifier,
visible = !isDismissed,
enter = enter,
exit = exit
) {
SwipeToDismiss(
modifier = modifier,
state = dismissState,
directions = directions,
background = { background(isDismissed) },
dismissContent = { content(isDismissed) }
)
}
}
@Composable
fun <T> ListContent(
innerPadding: InnerPadding,
items: List<T>,
onSwipe: (T) -> Unit,
onClick: (T) -> Unit
) {
LazyColumnFor(
modifier = modifier.padding(innerPadding),
items = items,
) { item ->
AnimatedSwipeDismiss(
item = item,
background = { isDismissed ->
/** define your background delete view here
* possibly:
Box(
modifier = Modifier.fillMaxSize(),
backgroundColor = Color.Red,
paddingStart = 20.dp,
paddingEnd = 20.dp,
gravity = ContentGravity.CenterEnd
) {
val alpha = animate( if (isDismissed) 0f else 1f)
Icon(Icons.Filled.Delete, tint = Color.White.copy(alpha = alpha))
}
using isDismissed to control alpha of the icon or content in the box
*/
},
content = { /* your item cell (feed your on click here) */ },
onDismiss = { onSwipe(it) }
}
}
@imallan
Copy link

imallan commented Oct 8, 2020

I've found val dismissState = rememberDismissState() remembering the dismissed state after the item was deleted from the List items. I've changed it to val dissmissState = remember { DismissState(...) } as a workaround.

@rex50
Copy link

rex50 commented Dec 16, 2021

Hey @bmc08gt,

Thanks for this code snippet but androidx.compose.runtime.onCommit is deprecated and removed in the latest compose stable versions (tested on compose version 1.0.5), so I've updated the snippet for AnimatedSwipeDismiss.kt, please consider updating your version.

import androidx.compose.animation.core.tween
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.ui.Modifier

@ExperimentalMaterialApi
@ExperimentalAnimationApi
@Composable
fun <T> AnimatedSwipeDismiss(
    modifier: Modifier = Modifier,
    item: T,
    background: @Composable (isDismissed: Boolean) -> Unit,
    content: @Composable (isDismissed: Boolean) -> Unit,
    directions: Set<DismissDirection> = setOf(DismissDirection.EndToStart),
    enter: EnterTransition = expandVertically(),
    exit: ExitTransition = shrinkVertically(
        animationSpec = tween(
            durationMillis = 500,
        )
    ),
    onDismiss: (T) -> Unit
) {
    val dismissState = rememberDismissState()
    val isDismissed = dismissState.isDismissed(DismissDirection.EndToStart)

    SideEffect {
        if (dismissState.isDismissed(DismissDirection.EndToStart)) {
            onDismiss(item)
        }
    }

    AnimatedVisibility(
        modifier = modifier,
        visible = !isDismissed,
        enter = enter,
        exit = exit
    ) {
        SwipeToDismiss(
            modifier = modifier,
            state = dismissState,
            directions = directions,
            background = { background(isDismissed) },
            dismissContent = { content(isDismissed) }
        )
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment