diff --git a/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt b/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt index 082bfffc42..0b41d2fa38 100644 --- a/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt +++ b/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt @@ -57,6 +57,7 @@ open class GestureHandler 0) { extractAllPointersData() - dispatchTouchEvent() + tryDispatchingTouchEvent() } } - fun updatePointerData(event: MotionEvent) { - if (event.actionMasked == MotionEvent.ACTION_DOWN || event.actionMasked == MotionEvent.ACTION_POINTER_DOWN) { - dispatchTouchDownEvent(event) - dispatchTouchMoveEvent(event) - } else if (event.actionMasked == MotionEvent.ACTION_UP || event.actionMasked == MotionEvent.ACTION_POINTER_UP) { - dispatchTouchMoveEvent(event) - dispatchTouchUpEvent(event) - } else if (event.actionMasked == MotionEvent.ACTION_MOVE) { - dispatchTouchMoveEvent(event) + fun updatePointerData(event: MotionEvent, sourceEvent: MotionEvent) { + eventTriggeringStateChangeInTouchEventHandler = sourceEvent + + when (event.actionMasked) { + MotionEvent.ACTION_DOWN, MotionEvent.ACTION_POINTER_DOWN -> { + handleTouchDownEvent(event) + handleTouchMoveEvent(event) + } + MotionEvent.ACTION_UP, MotionEvent.ACTION_POINTER_UP -> { + handleTouchMoveEvent(event) + handleTouchUpEvent(event) + } + MotionEvent.ACTION_MOVE -> { + handleTouchMoveEvent(event) + } } + + eventTriggeringStateChangeInTouchEventHandler = null } private fun extractAllPointersData() { @@ -490,7 +503,7 @@ open class GestureHandler 0) { handler!!.postDelayed({ activate() }, minDurationMs) @@ -83,6 +80,13 @@ class LongPressGestureHandler(context: Context) : GestureHandler() lastY = getLastPointerY(sourceEvent, averageTouches) } if (state == STATE_UNDETERMINED && sourceEvent.pointerCount >= minPointers) { - resetProgress() - offsetX = 0f - offsetY = 0f - velocityX = 0f - velocityY = 0f - velocityTracker = VelocityTracker.obtain() + initialize(sourceEvent) addVelocityMovement(velocityTracker, sourceEvent) begin() @@ -285,6 +280,15 @@ class PanGestureHandler(context: Context?) : GestureHandler() handler?.removeCallbacksAndMessages(null) } + override fun onInitialize(event: MotionEvent) { + resetProgress() + offsetX = 0f + offsetY = 0f + velocityX = 0f + velocityY = 0f + velocityTracker = VelocityTracker.obtain() + } + override fun onReset() { handler?.removeCallbacksAndMessages(null) velocityTracker?.let { diff --git a/android/src/main/java/com/swmansion/gesturehandler/core/PinchGestureHandler.kt b/android/src/main/java/com/swmansion/gesturehandler/core/PinchGestureHandler.kt index 28e8589382..4e5b85b759 100644 --- a/android/src/main/java/com/swmansion/gesturehandler/core/PinchGestureHandler.kt +++ b/android/src/main/java/com/swmansion/gesturehandler/core/PinchGestureHandler.kt @@ -52,16 +52,7 @@ class PinchGestureHandler : GestureHandler() { override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) { if (state == STATE_UNDETERMINED) { - val context = view!!.context - resetProgress() - scaleGestureDetector = ScaleGestureDetector(context, gestureListener) - val configuration = ViewConfiguration.get(context) - spanSlop = configuration.scaledTouchSlop.toFloat() - - // set the focal point to the position of the first pointer as NaN causes the event not to arrive - this.focalPointX = event.x - this.focalPointY = event.y - + initialize(sourceEvent) begin() } scaleGestureDetector?.onTouchEvent(sourceEvent) @@ -96,6 +87,18 @@ class PinchGestureHandler : GestureHandler() { resetProgress() } + override fun onInitialize(event: MotionEvent) { + resetProgress() + val context = view!!.context + val configuration = ViewConfiguration.get(context) + scaleGestureDetector = ScaleGestureDetector(context, gestureListener) + spanSlop = configuration.scaledTouchSlop.toFloat() + + // set the focal point to the position of the first pointer as NaN causes the event not to arrive + this.focalPointX = event.x + this.focalPointY = event.y + } + override fun resetProgress() { velocity = 0.0 scale = 1.0 diff --git a/android/src/main/java/com/swmansion/gesturehandler/core/RotationGestureHandler.kt b/android/src/main/java/com/swmansion/gesturehandler/core/RotationGestureHandler.kt index d3d12f4601..bfea235a78 100644 --- a/android/src/main/java/com/swmansion/gesturehandler/core/RotationGestureHandler.kt +++ b/android/src/main/java/com/swmansion/gesturehandler/core/RotationGestureHandler.kt @@ -43,13 +43,7 @@ class RotationGestureHandler : GestureHandler() { override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) { if (state == STATE_UNDETERMINED) { - resetProgress() - rotationGestureDetector = RotationGestureDetector(gestureListener) - - // set the anchor to the position of the first pointer as NaN causes the event not to arrive - this.anchorX = event.x - this.anchorY = event.y - + initialize(sourceEvent) begin() } rotationGestureDetector?.onTouchEvent(sourceEvent) @@ -75,6 +69,15 @@ class RotationGestureHandler : GestureHandler() { super.activate(force) } + override fun onInitialize(event: MotionEvent) { + resetProgress() + rotationGestureDetector = RotationGestureDetector(gestureListener) + + // set the anchor to the position of the first pointer as NaN causes the event not to arrive + this.anchorX = event.x + this.anchorY = event.y + } + override fun onReset() { rotationGestureDetector = null anchorX = Float.NaN diff --git a/android/src/main/java/com/swmansion/gesturehandler/core/TapGestureHandler.kt b/android/src/main/java/com/swmansion/gesturehandler/core/TapGestureHandler.kt index cb8adc77b1..e9048422c6 100644 --- a/android/src/main/java/com/swmansion/gesturehandler/core/TapGestureHandler.kt +++ b/android/src/main/java/com/swmansion/gesturehandler/core/TapGestureHandler.kt @@ -108,10 +108,7 @@ class TapGestureHandler : GestureHandler() { val state = state val action = sourceEvent.actionMasked if (state == STATE_UNDETERMINED) { - offsetX = 0f - offsetY = 0f - startX = getLastPointerX(sourceEvent, true) - startY = getLastPointerY(sourceEvent, true) + initialize(sourceEvent) } if (action == MotionEvent.ACTION_POINTER_UP || action == MotionEvent.ACTION_POINTER_DOWN) { offsetX += lastX - startX @@ -148,6 +145,13 @@ class TapGestureHandler : GestureHandler() { end() } + override fun onInitialize(event: MotionEvent) { + offsetX = 0f + offsetY = 0f + startX = getLastPointerX(event, true) + startY = getLastPointerY(event, true) + } + override fun onCancel() { handler?.removeCallbacksAndMessages(null) } diff --git a/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerModule.kt b/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerModule.kt index 98208b5710..4215fa29a8 100644 --- a/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerModule.kt +++ b/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerModule.kt @@ -431,9 +431,15 @@ class RNGestureHandlerModule(reactContext: ReactApplicationContext?) : override fun setGestureHandlerState(handlerTag: Int, newState: Int) { registry.getHandler(handlerTag)?.let { handler -> + // Try to initialize the handler in case it was not yet initialized + handler.initialize() + // Try to transition to the BEGIN state (possible only from UNDETERMINED) + // to force the correct event flow + handler.begin() + when (newState) { GestureHandler.STATE_ACTIVE -> handler.activate(force = true) - GestureHandler.STATE_BEGAN -> handler.begin() + GestureHandler.STATE_BEGAN -> {} GestureHandler.STATE_END -> handler.end() GestureHandler.STATE_FAILED -> handler.fail() GestureHandler.STATE_CANCELLED -> handler.cancel()