refactor: densité vivante, constante settle, tests de limite swipe-back
This commit is contained in:
3 files changed
+40
-19
No files matched your search
@@ -21,11 +21,12 @@ import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.ui.input.pointer.positionChange
|
||||
import androidx.compose.ui.input.pointer.util.VelocityTracker
|
||||
import androidx.compose.ui.layout.onSizeChanged
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.unit.dp
|
||||
import kotlin.math.abs
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
private const val SettleMillis = 200
|
||||
|
||||
object SwipeBackGesture {
|
||||
val EdgeZone = 24.dp
|
||||
const val CommitRatio = 0.4f
|
||||
@@ -44,10 +45,8 @@ fun SwipeBack(
|
||||
background: @Composable () -> Unit,
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
val density = LocalDensity.current
|
||||
val scope = rememberCoroutineScope()
|
||||
val offset = remember { Animatable(0f) }
|
||||
val edgeZonePx = with(density) { SwipeBackGesture.EdgeZone.toPx() }
|
||||
var widthPx by remember { mutableFloatStateOf(0f) }
|
||||
val showBackground by remember { derivedStateOf { offset.value > 0f } }
|
||||
|
||||
@@ -66,7 +65,7 @@ fun SwipeBack(
|
||||
.pointerInput(Unit) {
|
||||
awaitEachGesture {
|
||||
val down = awaitFirstDown()
|
||||
if (down.position.x > edgeZonePx) return@awaitEachGesture
|
||||
if (down.position.x > SwipeBackGesture.EdgeZone.toPx()) return@awaitEachGesture
|
||||
|
||||
val tracker = VelocityTracker()
|
||||
tracker.addPosition(down.uptimeMillis, down.position)
|
||||
@@ -81,7 +80,7 @@ fun SwipeBack(
|
||||
|
||||
if (change.isConsumed && !change.pressed && change.previousPressed) {
|
||||
if (dragging) {
|
||||
scope.launch { offset.animateTo(0f, tween(200)) }
|
||||
scope.launch { offset.animateTo(0f, tween(SettleMillis)) }
|
||||
}
|
||||
break
|
||||
}
|
||||
@@ -116,7 +115,7 @@ fun SwipeBack(
|
||||
if (change.changedToUpIgnoreConsumed()) {
|
||||
if (dragging) {
|
||||
val velocityDpPerSec =
|
||||
tracker.calculateVelocity().x / density.density
|
||||
tracker.calculateVelocity().x / density
|
||||
val commit = SwipeBackGesture.shouldCommit(
|
||||
offsetPx = dragged,
|
||||
containerWidthPx = widthPx,
|
||||
@@ -125,11 +124,11 @@ fun SwipeBack(
|
||||
scope.launch {
|
||||
if (commit) {
|
||||
offset.snapTo(dragged)
|
||||
offset.animateTo(widthPx, tween(200))
|
||||
offset.animateTo(widthPx, tween(SettleMillis))
|
||||
onBack()
|
||||
} else {
|
||||
offset.snapTo(dragged)
|
||||
offset.animateTo(0f, tween(200))
|
||||
offset.animateTo(0f, tween(SettleMillis))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,4 +49,26 @@ class SwipeBackGestureTest {
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `pas de commit a la limite exacte de 40 pourcent sans velocite`() {
|
||||
assertFalse(
|
||||
SwipeBackGesture.shouldCommit(
|
||||
offsetPx = 400f,
|
||||
containerWidthPx = 1000f,
|
||||
velocityDpPerSec = 0f,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `pas de commit avec un offset negatif`() {
|
||||
assertFalse(
|
||||
SwipeBackGesture.shouldCommit(
|
||||
offsetPx = -100f,
|
||||
containerWidthPx = 1000f,
|
||||
velocityDpPerSec = 0f,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user