@@ -39,6 +39,7 @@ import androidx.compose.ui.draw.clip
3939import androidx.compose.ui.graphics.Color
4040import androidx.compose.ui.graphics.graphicsLayer
4141import androidx.compose.ui.input.pointer.pointerInput
42+ import androidx.compose.ui.input.pointer.util.VelocityTracker
4243import androidx.compose.ui.layout.onGloballyPositioned
4344import androidx.compose.ui.platform.LocalDensity
4445import androidx.compose.ui.text.font.FontWeight
@@ -54,6 +55,7 @@ import top.yukonga.miuix.kmp.utils.G2RoundedCornerShape
5455import top.yukonga.miuix.kmp.utils.MiuixPopupUtils.Companion.DialogLayout
5556import top.yukonga.miuix.kmp.utils.PredictiveBackHandler
5657import top.yukonga.miuix.kmp.utils.getWindowSize
58+ import kotlin.math.abs
5759
5860/* *
5961 * A bottom sheet that slides up from the bottom of the screen.
@@ -338,6 +340,7 @@ private fun DragHandleArea(
338340 val isPressing = remember { mutableFloatStateOf(0f ) }
339341 val pressScale = remember { Animatable (1f ) }
340342 val pressWidth = remember { Animatable (45f ) }
343+ val velocityTracker = remember { VelocityTracker () }
341344
342345 Box (
343346 modifier = Modifier
@@ -349,6 +352,7 @@ private fun DragHandleArea(
349352 coroutineScope.launch {
350353 dragStartOffset.floatValue = dragOffsetY.value
351354 dragOffsetY.snapTo(dragOffsetY.value)
355+ velocityTracker.resetTracking()
352356 // Animate press effect
353357 isPressing.floatValue = 1f
354358 launch {
@@ -384,18 +388,30 @@ private fun DragHandleArea(
384388
385389 val currentOffset = dragOffsetY.value
386390 val dragDelta = currentOffset - dragStartOffset.floatValue
391+ val velocity = velocityTracker.calculateVelocity().y
392+ val velocityThreshold = 500f
393+
394+ println (" Drag ended. Delta: $dragDelta , Velocity: $velocity " )
387395
388396 when {
389- // Dragged down significantly -> dismiss
390- dragDelta > 150f -> {
397+ // Dragged down far enough or has strong downward velocity -> dismiss
398+ (abs(velocity) > velocityThreshold || dragDelta.dp >= 200 .dp) && velocity <= 0 -> {
391399 onDismissRequest?.invoke()
392400 val windowHeightPx = windowHeight.value * density.density
393401 dragOffsetY.animateTo(
394402 targetValue = windowHeightPx,
395403 animationSpec = tween(durationMillis = 250 )
396404 )
397405 }
398- // Reset to original position (including overscroll bounce back)
406+ // Dragged up far enough or has strong upward velocity -> reset to original position
407+ abs(velocity) > velocityThreshold && velocity > 0 -> {
408+ dragOffsetY.animateTo(
409+ targetValue = 0f ,
410+ animationSpec = tween(durationMillis = 250 )
411+ )
412+ dimAlpha.value = 1f
413+ }
414+ // Not dragged far enough -> reset to original position
399415 else -> {
400416 dragOffsetY.animateTo(
401417 targetValue = 0f ,
@@ -406,8 +422,10 @@ private fun DragHandleArea(
406422 }
407423 }
408424 },
409- onVerticalDrag = { _ , dragAmount ->
425+ onVerticalDrag = { change , dragAmount ->
410426 coroutineScope.launch {
427+ velocityTracker.addPosition(change.uptimeMillis, change.position)
428+
411429 val newOffset = dragOffsetY.value + dragAmount
412430
413431 // Apply damping effect when dragging upward (negative offset)
0 commit comments