From 1a262a7c7ddab1ec67112731e6bebef3f185f91c Mon Sep 17 00:00:00 2001 From: Andrew Goodale Date: Sun, 27 Aug 2017 22:03:40 -0700 Subject: [PATCH] Fix panResponder nativeEvent.locationX and locationY values on touch move Summary: Fixes #12591 The Android JSTouchDispatcher was using `mTargetCoordinates` when creating the TouchEvent for a move. However, these are final values which are set when the touch down is received. When the user's finger moves, it's important to be able to track the coordinates of the touch as it moves. Thus, we need to update the x,y coordinates by calling `TouchTargetHelper` on each move event. Closes https://github.com/facebook/react-native/pull/15123 Reviewed By: achen1 Differential Revision: D5476663 Pulled By: shergin fbshipit-source-id: ce79e96490f3657a13f9114fcc93e80d5fdbebaf --- .../react/uimanager/JSTouchDispatcher.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSTouchDispatcher.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSTouchDispatcher.java index ba8d56be8ad2fe..86abf04fdd3f19 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSTouchDispatcher.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSTouchDispatcher.java @@ -11,7 +11,6 @@ import android.view.MotionEvent; import android.view.ViewGroup; - import com.facebook.common.logging.FLog; import com.facebook.infer.annotation.Assertions; import com.facebook.react.common.ReactConstants; @@ -74,12 +73,7 @@ public void handleTouchEvent(MotionEvent ev, EventDispatcher eventDispatcher) { // this gesture mChildIsHandlingNativeGesture = false; mGestureStartTime = ev.getEventTime(); - mTargetTag = TouchTargetHelper.findTargetTagAndCoordinatesForTouch( - ev.getX(), - ev.getY(), - mRootViewGroup, - mTargetCoordinates, - null); + mTargetTag = findTargetTagAndSetCoordinates(ev); eventDispatcher.dispatchEvent( TouchEvent.obtain( mTargetTag, @@ -103,6 +97,7 @@ public void handleTouchEvent(MotionEvent ev, EventDispatcher eventDispatcher) { } else if (action == MotionEvent.ACTION_UP) { // End of the gesture. We reset target tag to -1 and expect no further event associated with // this gesture. + findTargetTagAndSetCoordinates(ev); eventDispatcher.dispatchEvent( TouchEvent.obtain( mTargetTag, @@ -116,6 +111,7 @@ public void handleTouchEvent(MotionEvent ev, EventDispatcher eventDispatcher) { mGestureStartTime = TouchEvent.UNSET; } else if (action == MotionEvent.ACTION_MOVE) { // Update pointer position for current gesture + findTargetTagAndSetCoordinates(ev); eventDispatcher.dispatchEvent( TouchEvent.obtain( mTargetTag, @@ -165,6 +161,12 @@ public void handleTouchEvent(MotionEvent ev, EventDispatcher eventDispatcher) { } } + private int findTargetTagAndSetCoordinates(MotionEvent ev) { + // This method updates `mTargetCoordinates` with coordinates for the motion event. + return TouchTargetHelper.findTargetTagAndCoordinatesForTouch( + ev.getX(), ev.getY(), mRootViewGroup, mTargetCoordinates, null); + } + private void dispatchCancelEvent(MotionEvent androidEvent, EventDispatcher eventDispatcher) { // This means the gesture has already ended, via some other CANCEL or UP event. This is not // expected to happen very often as it would mean some child View has decided to intercept the