Reputation: 17858
I'm using material3 1.2.0.
When using SwipeToDismissBox
and rememberSwipeToDismissBoxState
I see a problem, that I can't detect if the user has already swiped far enough to trigger a delete event or if stopping the swipe would simply cancel the swipe delete without any event...
What I want is that the background does change its color as soon as the swipe would result in an action but therefore I need to detect what the result of stopping the swipe would be.
Code
Here's my code so far:
val deleteValue = SwipeToDismissBoxValue.StartToEnd
val state = rememberSwipeToDismissBoxState(
confirmValueChange = {
if (it == deleteValue){
L.tag("SWIPE-DISMISS").d { "onDelete..." }
onDelete()
true
} else false
}
)
SwipeToDismissBox(
modifier = Modifier,
state = state,
enableDismissFromEndToStart = false,
enableDismissFromStartToEnd = true,
backgroundContent = {
// detect if releasing at the current swipe position would trigger a delete event or not
// this does not work, it triggers at ~50% of swiping instead of the default threshold of 56dp...
val success = dismissState.targetValue == deleteValue
val color by animateColorAsState(
if (success) Color.Red else Color.Transparent,
label = ""
)
Box(
Modifier
.fillMaxSize()
.background(color)
) {
// ...
}
}) {
content()
}
Material 1.1.2
Using the targetState
did work in the past with SwipeToDismiss
from material3 1.1.2... For me it seems that the targetState
is currently broken.
Solution
I can solve that manually by using the 56.dp
from SwipeToDismissBoxDefaults.positionalThreshold
like following to determine my success flag:
val minOffset = with(LocalDensity.current) { threshold.toPx() }
val success = dismissState.progress != 0f && abs(dismissState.requireOffset()) > minOffset
But I really want to avoid this manual distance checking...
Upvotes: 2
Views: 1170
Reputation: 13
rememberSwipeToDismissBoxState
has a property called positionalThreshold
. You can set the swipe threshold using that.
So your code becomes:
val threshold: Float = with(LocalConfiguration.current) {
(this.screenWidthDp * swipePercentage).dp.value
}
val state = rememberSwipeToDismissBoxState(
confirmValueChange = {
if (it == deleteValue){
L.tag("SWIPE-DISMISS").d { "onDelete..." }
onDelete()
true
} else false
},
positionalThreshold = { threshold }
)
Where swipePercentage
is the percentage of the screen that the row must have been swiped.
Upvotes: 0