diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSPointerDispatcher.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSPointerDispatcher.java index 88eec78e2d875a..13701c36f65756 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSPointerDispatcher.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSPointerDispatcher.java @@ -70,6 +70,9 @@ public void onChildStartedNativeGesture( dispatchCancelEventForTarget(childView, motionInRoot, eventDispatcher); mChildHandlingNativeGesture = childView.getId(); + + // clear "previous" state since interaction was canceled + resetPreviousStateForMotionEvent(motionEvent); } private MotionEvent convertMotionToRootFrame(View childView, MotionEvent childMotion) { @@ -84,6 +87,28 @@ private MotionEvent convertMotionToRootFrame(View childView, MotionEvent childMo return motionInRoot; } + private void updatePreviousStateFromEvent(MotionEvent event, PointerEventState eventState) { + // Caching the event state so we have a new "last" + mLastHitPathByPointerId = eventState.getHitPathByPointerId(); + mLastEventCoordinatesByPointerId = eventState.getEventCoordinatesByPointerId(); + mLastButtonState = event.getButtonState(); + + // Clean up any stale pointerIds + Set allPointerIds = mLastEventCoordinatesByPointerId.keySet(); + mHoveringPointerIds.retainAll(allPointerIds); + } + + private void resetPreviousStateForMotionEvent(MotionEvent event) { + int activePointerId = event.getPointerId(event.getActionIndex()); + if (mLastHitPathByPointerId != null) { + mLastHitPathByPointerId.remove(activePointerId); + } + if (mLastEventCoordinatesByPointerId != null) { + mLastEventCoordinatesByPointerId.remove(activePointerId); + } + mLastButtonState = 0; + } + public void onChildEndedNativeGesture() { // There should be only one child gesture at any given time. We can safely turn off the flag. mChildHandlingNativeGesture = -1; @@ -368,14 +393,7 @@ public void handleMotionEvent( return; } - // Caching the event state so we have a new "last" - mLastHitPathByPointerId = eventState.getHitPathByPointerId(); - mLastEventCoordinatesByPointerId = eventState.getEventCoordinatesByPointerId(); - mLastButtonState = motionEvent.getButtonState(); - - // Clean up any stale pointerIds - Set allPointerIds = mLastEventCoordinatesByPointerId.keySet(); - mHoveringPointerIds.retainAll(allPointerIds); + updatePreviousStateFromEvent(motionEvent, eventState); } private static boolean isAnyoneListeningForBubblingEvent(