@Override public int reactTagForTouch(float touchX, float touchY) { /* * Make sure we don't find any children if the pointer events are set to BOX_ONLY. * There is no need to special-case any other modes, because if PointerEvents are set to: * a) PointerEvents.AUTO - all children are included, nothing to exclude * b) PointerEvents.NONE - this method will NOT be executed, because the View will be filtered * out by TouchTargetHelper. * c) PointerEvents.BOX_NONE - TouchTargetHelper will make sure that {@link #reactTagForTouch()} * doesn't return getId(). */ SoftAssertions.assertCondition( mPointerEvents != PointerEvents.NONE, "TouchTargetHelper should not allow calling this method when pointer events are NONE"); if (mPointerEvents != PointerEvents.BOX_ONLY) { NodeRegion nodeRegion = virtualNodeRegionWithinBounds(touchX, touchY); if (nodeRegion != null) { return nodeRegion.getReactTag(touchX, touchY); } } // no children found return getId(); }
@Override public boolean onInterceptTouchEvent(MotionEvent ev) { final long downTime = ev.getDownTime(); if (downTime != mLastTouchDownTime) { mLastTouchDownTime = downTime; if (interceptsTouchEvent(ev.getX(), ev.getY())) { return true; } } if (mOnInterceptTouchEventListener != null && mOnInterceptTouchEventListener.onInterceptTouchEvent(this, ev)) { return true; } // We intercept the touch event if the children are not supposed to receive it. if (mPointerEvents == PointerEvents.NONE || mPointerEvents == PointerEvents.BOX_ONLY) { return true; } return super.onInterceptTouchEvent(ev); }
@Override public boolean onTouchEvent(MotionEvent ev) { // We do not accept the touch event if this view is not supposed to receive it. if (mPointerEvents == PointerEvents.NONE) { return false; } if (mPointerEvents == PointerEvents.BOX_NONE) { // We cannot always return false here because some child nodes could be flatten into this View NodeRegion nodeRegion = virtualNodeRegionWithinBounds(ev.getX(), ev.getY()); if (nodeRegion == null) { // no child to handle this touch event, bailing out. return false; } } // The root view always assumes any view that was tapped wants the touch // and sends the event to JS as such. // We don't need to do bubbling in native (it's already happening in JS). // For an explanation of bubbling and capturing, see // http://javascript.info/tutorial/bubbling-and-capturing#capturing return true; }
private static PointerEvents parsePointerEvents(@Nullable String pointerEventsStr) { if (pointerEventsStr != null) { switch (pointerEventsStr) { case "none": return PointerEvents.NONE; case "auto": return PointerEvents.AUTO; case "box-none": return PointerEvents.BOX_NONE; case "box-only": return PointerEvents.BOX_ONLY; } } // default or invalid return PointerEvents.AUTO; }
@Override public PointerEventsConfig getPointerEventsConfigForView(View view) { PointerEvents pointerEvents; pointerEvents = view instanceof ReactPointerEventsView ? ((ReactPointerEventsView) view).getPointerEvents() : PointerEvents.AUTO; // Views that are disabled should never be the target of pointer events. However, their children // can be because some views (SwipeRefreshLayout) use enabled but still have children that can // be valid targets. if (!view.isEnabled()) { if (pointerEvents == PointerEvents.AUTO) { return PointerEventsConfig.BOX_NONE; } else if (pointerEvents == PointerEvents.BOX_ONLY) { return PointerEventsConfig.NONE; } } switch (pointerEvents) { case BOX_ONLY: return PointerEventsConfig.BOX_ONLY; case BOX_NONE: return PointerEventsConfig.BOX_NONE; case NONE: return PointerEventsConfig.NONE; } return PointerEventsConfig.AUTO; }
@ReactProp(name = ViewProps.POINTER_EVENTS) public void setPointerEvents(ReactViewGroup view, @Nullable String pointerEventsStr) { if (pointerEventsStr == null) { view.setPointerEvents(PointerEvents.AUTO); } else { PointerEvents pointerEvents = PointerEvents.valueOf(pointerEventsStr.toUpperCase(Locale.US).replace("-", "_")); view.setPointerEvents(pointerEvents); } }
@Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (mOnInterceptTouchEventListener != null && mOnInterceptTouchEventListener.onInterceptTouchEvent(this, ev)) { return true; } // We intercept the touch event if the children are not supposed to receive it. if (mPointerEvents == PointerEvents.NONE || mPointerEvents == PointerEvents.BOX_ONLY) { return true; } return super.onInterceptTouchEvent(ev); }
@Override public boolean onTouchEvent(MotionEvent ev) { // We do not accept the touch event if this view is not supposed to receive it. if (mPointerEvents == PointerEvents.NONE || mPointerEvents == PointerEvents.BOX_NONE) { return false; } // The root view always assumes any view that was tapped wants the touch // and sends the event to JS as such. // We don't need to do bubbling in native (it's already happening in JS). // For an explanation of bubbling and capturing, see // http://javascript.info/tutorial/bubbling-and-capturing#capturing return true; }
@ReactProp(name = "pointerEvents") public void setPointerEvents(ReactViewGroup view, @Nullable String pointerEventsStr) { if (pointerEventsStr != null) { PointerEvents pointerEvents = PointerEvents.valueOf(pointerEventsStr.toUpperCase(Locale.US).replace("-", "_")); view.setPointerEvents(pointerEvents); } }
@Override public PointerEvents getPointerEvents() { return mPointerEvents; }
void setPointerEvents(PointerEvents pointerEvents) { mPointerEvents = pointerEvents; }