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
This commit is contained in:
Luna Wei
2022-08-31 11:32:57 -07:00
committed by Facebook GitHub Bot
parent 4352459781
commit 823f6b7704
3 changed files with 24 additions and 3 deletions
@@ -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
@@ -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);
}
@@ -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