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
This commit is contained in:
Denis Koroskin 2015-12-22 13:43:18 -08:00 committed by facebook-github-bot-3
parent 83c2e0303b
commit d0de0767e3
1 changed files with 17 additions and 1 deletions

View File

@ -173,7 +173,23 @@ public class TouchTargetHelper {
// This view can't be the target, but its children might // This view can't be the target, but its children might
if (view instanceof ViewGroup) { if (view instanceof ViewGroup) {
View targetView = findTouchTargetView(eventCoords, (ViewGroup) view); 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; return null;