在Android Jetpack compose 中如何实现GestureDetector.SimpleOnGestureListener.......?
In Android Jetpack compose how to achieve GestureDetector.SimpleOnGestureListener.....?
我想观察 onFling 函数来检测 Velocityx 和 Velocity Means Swiping force/Velocity。在 android 中,我们将其附加到 android view.But 找不到如何在 Jetpack compose 中调用它的方法或在 Jetpack compose 中找到替代函数...?
请使用 Animation-in-Compose Codelab 以更好地理解,但现在,您可以通过以下方式实现类似的效果
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) }
}
我不建议仅从这里尝试理解此代码,您可能应该参考手头的文档,同时参加代码实验室。这在 compose-sample 应用中的一个简单列表项上实现了 swipe-to-dismiss 功能,您将在代码实验室的开头找到链接到的代码。以下是all the sample apps 发布的compose,供大家参考。
我想观察 onFling 函数来检测 Velocityx 和 Velocity Means Swiping force/Velocity。在 android 中,我们将其附加到 android view.But 找不到如何在 Jetpack compose 中调用它的方法或在 Jetpack compose 中找到替代函数...?
请使用 Animation-in-Compose Codelab 以更好地理解,但现在,您可以通过以下方式实现类似的效果
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) }
}
我不建议仅从这里尝试理解此代码,您可能应该参考手头的文档,同时参加代码实验室。这在 compose-sample 应用中的一个简单列表项上实现了 swipe-to-dismiss 功能,您将在代码实验室的开头找到链接到的代码。以下是all the sample apps 发布的compose,供大家参考。