From d0de0767e3c2a034aca4d4cf5330b0937ea0dd9f Mon Sep 17 00:00:00 2001 From: Denis Koroskin Date: Tue, 22 Dec 2015 13:43:18 -0800 Subject: [PATCH] Implement touch intercepting in RCTView Summary: public React allows excluding certain elements from touch handling by assigning `PointerEvents` filter to them, such as BOX_NONE - this element will not receive touch but its children will, BOX_ONLY - only this element will receive pointer event and not children, NONE - neither this element nor its children will receive pointer events, and AUTO - pointer events are allowed for both this element and its children. This diff adds PointerEvents support to flat RCTView. Most of the implementation is copied from ReactViewManager/ReactViewGroup. One small change is made to TouchTargetHelper to ensure that it works correctly with virtual nodes when their parent has PointerEvents set to PointerEvents.BOX_NONE. Reviewed By: ahmedre Differential Revision: D2784208 fb-gh-sync-id: 4b831f9b1bfb8014a99d7b33534ae7ff7b4ab498 --- .../react/uimanager/TouchTargetHelper.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/TouchTargetHelper.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/TouchTargetHelper.java index 8564258babe7b4..9635d5bf6f1f10 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/TouchTargetHelper.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/TouchTargetHelper.java @@ -173,7 +173,23 @@ private static boolean isTransformedTouchPointInView( // This view can't be the target, but its children might if (view instanceof ViewGroup) { View targetView = findTouchTargetView(eventCoords, (ViewGroup) view); - return targetView != view ? targetView : null; + if (targetView != view) { + return targetView; + } + + // PointerEvents.BOX_NONE means that this react element cannot receive pointer events. + // However, there might be virtual children that can receive pointer events, in which case + // we still want to return this View and dispatch a pointer event to the virtual element. + // Note that this currently only applies to Nodes/FlatViewGroup as it's the only class that + // is both a ViewGroup and ReactCompoundView (ReactTextView is a ReactCompoundView but not a + // ViewGroup). + if (view instanceof ReactCompoundView) { + int reactTag = ((ReactCompoundView)view).reactTagForTouch(eventCoords[0], eventCoords[1]); + if (reactTag != view.getId()) { + // make sure we exclude the View itself because of the PointerEvents.BOX_NONE + return view; + } + } } return null;