From 823f6b770496fbbbf7aade4dc431e392421b9ea4 Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Wed, 31 Aug 2022 11:32:57 -0700 Subject: [PATCH] NativeGestureUtil.notifyNativeGestureEnded is called Summary: Changelog: [Internal] - Make sure `onChildEndedNativeGesture` is called for view managers that call `onChildStartedNativeGesture` This affects `JSTouchDispatcher`, `JSPointerDispatcher` as they track what view is reporting native gesturing handling. This is a bug that view managers never shared the fact that they've stopped managing a native gesture. Both `JSTouchDispatcher`, `JSPointerDispatcher` get around this by manually resetting their internal flag on ACTION_DOWN event (we will get rid of this in a later diff) Reviewed By: javache Differential Revision: D38850609 fbshipit-source-id: ef4afb591249bb621f42667608dc1ef20424b65c --- .../react/uimanager/JSPointerDispatcher.java | 3 --- .../react/views/drawer/ReactDrawerLayout.java | 12 ++++++++++++ .../views/swiperefresh/ReactSwipeRefreshLayout.java | 12 ++++++++++++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSPointerDispatcher.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSPointerDispatcher.java index 9aa3f873456..d547137ccee 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSPointerDispatcher.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSPointerDispatcher.java @@ -109,9 +109,6 @@ public class JSPointerDispatcher { // First down pointer if (action == MotionEvent.ACTION_DOWN) { - - // Reset mChildHandlingNativeGesture like JSTouchDispatcher does - mChildHandlingNativeGesture = -1; mPrimaryPointerId = motionEvent.getPointerId(actionIndex); // Start a "down" coalescing key diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayout.java b/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayout.java index 3cebb40d7bd..ab9bb7d30d3 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayout.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayout.java @@ -25,6 +25,7 @@ import com.facebook.react.uimanager.events.NativeGestureUtil; public static final int DEFAULT_DRAWER_WIDTH = LayoutParams.MATCH_PARENT; private int mDrawerPosition = Gravity.START; private int mDrawerWidth = DEFAULT_DRAWER_WIDTH; + private boolean mDragging = false; public ReactDrawerLayout(ReactContext reactContext) { super(reactContext); @@ -35,6 +36,7 @@ import com.facebook.react.uimanager.events.NativeGestureUtil; try { if (super.onInterceptTouchEvent(ev)) { NativeGestureUtil.notifyNativeGestureStarted(this, ev); + mDragging = true; return true; } } catch (IllegalArgumentException e) { @@ -47,6 +49,16 @@ import com.facebook.react.uimanager.events.NativeGestureUtil; return false; } + @Override + public boolean onTouchEvent(MotionEvent ev) { + int action = ev.getActionMasked(); + if (action == MotionEvent.ACTION_UP && mDragging) { + NativeGestureUtil.notifyNativeGestureEnded(this, ev); + mDragging = false; + } + return super.onTouchEvent(ev); + } + /* package */ void openDrawer() { openDrawer(mDrawerPosition); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout.java b/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout.java index ab1cd9a9ca7..f0d9111ab15 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout.java @@ -25,6 +25,7 @@ public class ReactSwipeRefreshLayout extends SwipeRefreshLayout { private int mTouchSlop; private float mPrevTouchX; private boolean mIntercepted; + private boolean mNativeGestureStarted = false; public ReactSwipeRefreshLayout(ReactContext reactContext) { super(reactContext); @@ -86,6 +87,7 @@ public class ReactSwipeRefreshLayout extends SwipeRefreshLayout { public boolean onInterceptTouchEvent(MotionEvent ev) { if (shouldInterceptTouchEvent(ev) && super.onInterceptTouchEvent(ev)) { NativeGestureUtil.notifyNativeGestureStarted(this, ev); + mNativeGestureStarted = true; // If the pull-to-refresh gesture is interrupted by a parent with its own // onInterceptTouchEvent then the refresh indicator gets stuck on-screen @@ -99,6 +101,16 @@ public class ReactSwipeRefreshLayout extends SwipeRefreshLayout { return false; } + @Override + public boolean onTouchEvent(MotionEvent ev) { + int action = ev.getActionMasked(); + if (action == MotionEvent.ACTION_UP && mNativeGestureStarted) { + NativeGestureUtil.notifyNativeGestureEnded(this, ev); + mNativeGestureStarted = false; + } + return super.onTouchEvent(ev); + } + /** * {@link SwipeRefreshLayout} completely bypasses ViewGroup's "disallowIntercept" by overriding * {@link ViewGroup#onInterceptTouchEvent} and never calling super.onInterceptTouchEvent(). This