From a099869edd1cfa9be2a66e44ca22eb5da17be763 Mon Sep 17 00:00:00 2001 From: Ahmed El-Helw Date: Mon, 11 Apr 2016 13:50:01 -0700 Subject: [PATCH] Don't intercept touch for Nodes after down event Summary: With nodes, it's possible for a touchable region to not be explicitly mounted to a View. To work around this (and allow the region to be the handler of the touch event), FlatViewGroup intercepts touch events when the touch lies within any of the virtual NodeRegions. This can sometimes be wrong - the canonical example is when touch starts outside of a particular FlatViewGroup (so someone else, for example a sibling) intercepts the touch event, and then the person moves over a different FlatViewGroup, causing it to intercept the touch event when it shouldn't. To fix this, we only allow intercepting touch events due to NodeRegions on the down event. Reviewed By: astreet Differential Revision: D3160152 --- .../com/facebook/react/flat/FlatViewGroup.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatViewGroup.java b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatViewGroup.java index 94dfd898c..5f227d568 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatViewGroup.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatViewGroup.java @@ -85,6 +85,7 @@ import com.facebook.react.views.image.ImageLoadEvent; private boolean mNeedsOffscreenAlphaCompositing = false; private Drawable mHotspot; private PointerEvents mPointerEvents = PointerEvents.AUTO; + private long mLastTouchDownTime; private @Nullable OnInterceptTouchEventListener mOnInterceptTouchEventListener; /* package */ FlatViewGroup(Context context) { @@ -136,11 +137,7 @@ import com.facebook.react.views.image.ImageLoadEvent; @Override public boolean interceptsTouchEvent(float touchX, float touchY) { NodeRegion nodeRegion = anyNodeRegionWithinBounds(touchX, touchY); - if (nodeRegion != null) { - return nodeRegion.mIsVirtual; - } - - return false; + return nodeRegion != null && nodeRegion.mIsVirtual; } @Override @@ -267,8 +264,12 @@ import com.facebook.react.views.image.ImageLoadEvent; @Override public boolean onInterceptTouchEvent(MotionEvent ev) { - if (interceptsTouchEvent(ev.getX(), ev.getY())) { - return true; + final long downTime = ev.getDownTime(); + if (downTime != mLastTouchDownTime) { + mLastTouchDownTime = downTime; + if (interceptsTouchEvent(ev.getX(), ev.getY())) { + return true; + } } if (mOnInterceptTouchEventListener != null &&