I want to observe onFling Function to detect Velocityx and Velocity Means Swiping force/Velocity. In android we attach this to the android view.But donot find a way how to call this in Jetpack compose or alternative function for this in jetpack compose…?
Advertisement
Answer
Please take the Animation-in-Compose codelab to understand better, but for now, here’s how you can achieve something similar
private fun Modifier.swipeToDismiss( onDismissed: () -> Unit ): Modifier = composed { // This `Animatable` stores the horizontal offset for the element. val offsetX = remember { Animatable(0f) } pointerInput(Unit) { // Used to calculate a settling position of a fling animation. val decay = splineBasedDecay<Float>(this) // Wrap in a coroutine scope to use suspend functions for touch events and animation. coroutineScope { while (true) { // Wait for a touch down event. val pointerId = awaitPointerEventScope { awaitFirstDown().id } // Interrupt any ongoing animation. offsetX.stop() // Prepare for drag events and record velocity of a fling. val velocityTracker = VelocityTracker() // Wait for drag events. awaitPointerEventScope { horizontalDrag(pointerId) { change -> // Record the position after offset val horizontalDragOffset = offsetX.value + change.positionChange().x launch { // Overwrite the `Animatable` value while the element is dragged. offsetX.snapTo(horizontalDragOffset) } // Record the velocity of the drag. velocityTracker.addPosition(change.uptimeMillis, change.position) // Consume the gesture event, not passed to external change.consumePositionChange() } } // Dragging finished. Calculate the velocity of the fling. val velocity = velocityTracker.calculateVelocity().x // Calculate where the element eventually settles after the fling animation. val targetOffsetX = decay.calculateTargetValue(offsetX.value, velocity) // The animation should end as soon as it reaches these bounds. offsetX.updateBounds( lowerBound = -size.width.toFloat(), upperBound = size.width.toFloat() ) launch { if (targetOffsetX.absoluteValue <= size.width) { // Not enough velocity; Slide back to the default position. offsetX.animateTo(targetValue = 0f, initialVelocity = velocity) } else { // Enough velocity to slide away the element to the edge. offsetX.animateDecay(velocity, decay) // The element was swiped away. onDismissed() } } } } } // Apply the horizontal offset to the element. .offset { IntOffset(offsetX.value.roundToInt(), 0) } }
I would not recommend trying to comprehend this code just from here, you should probably refer to the documentation at hand, while taking the codelab as well. This implements a swipe-to-dismiss functionality on a simple list item in a compose-sample app, the code to which you will find linked to in the start of the codelab. Here are all the sample apps published for compose, for your reference.