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
This commit is contained in:
Ahmed El-Helw
2016-04-11 13:50:01 -07:00
parent cbf195e165
commit a099869edd

View File

@@ -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 &&