Fix touch target computation

Differential Revision: D2516811

fb-gh-sync-id: 1f3490f969912f1eb8f4d49a5daa976314bbc25f
This commit is contained in:
Andrei Coman 2015-10-07 01:45:12 -07:00 committed by facebook-github-bot-7
parent fb90ba6ded
commit c805157cac
3 changed files with 20 additions and 10 deletions

View File

@ -142,7 +142,7 @@ public class ReactRootView extends SizeMonitoringFrameLayout implements RootView
// {@link #findTargetTagForTouch} to find react view ID that will be responsible for handling // {@link #findTargetTagForTouch} to find react view ID that will be responsible for handling
// this gesture // this gesture
mChildIsHandlingNativeGesture = false; mChildIsHandlingNativeGesture = false;
mTargetTag = TouchTargetHelper.findTargetTagForTouch(ev.getRawY(), ev.getRawX(), this); mTargetTag = TouchTargetHelper.findTargetTagForTouch(ev.getY(), ev.getX(), this);
eventDispatcher.dispatchEvent(new TouchEvent(mTargetTag, TouchEventType.START, ev)); eventDispatcher.dispatchEvent(new TouchEvent(mTargetTag, TouchEventType.START, ev));
} else if (mChildIsHandlingNativeGesture) { } else if (mChildIsHandlingNativeGesture) {
// If the touch was intercepted by a child, we've already sent a cancel event to JS for this // If the touch was intercepted by a child, we've already sent a cancel event to JS for this

View File

@ -79,17 +79,27 @@ public class TouchTargetHelper {
// parent, therefore `getGlobalVisibleRect` call will return bogus result as it treat view // parent, therefore `getGlobalVisibleRect` call will return bogus result as it treat view
// with no parent as a root of the view hierarchy. To prevent this from happening we check // with no parent as a root of the view hierarchy. To prevent this from happening we check
// that view has a parent before visiting it. // that view has a parent before visiting it.
if (child.getParent() != null && child.getGlobalVisibleRect(mVisibleRect)) { if (child.getParent() != null && isTouchPointInView(eventX, eventY, viewGroup, child)) {
if (eventX >= mVisibleRect.left && eventX <= mVisibleRect.right // Apply offset to event coordinates to transform them into the coordinate space of the
&& eventY >= mVisibleRect.top && eventY <= mVisibleRect.bottom) { // child view, taken from {@link ViewGroup#dispatchTransformedTouchEvent()}.
View targetView = findTouchTargetViewWithPointerEvents(eventX, eventY, child); eventX += viewGroup.getScrollX() - child.getLeft();
if (targetView != null) { eventY += viewGroup.getScrollY() - child.getTop();
return targetView; View targetView = findTouchTargetViewWithPointerEvents(eventX, eventY, child);
} if (targetView != null) {
return targetView;
} }
} }
} }
return viewGroup; return viewGroup;
}
// Taken from {@link ViewGroup#isTransformedTouchPointInView()}
private static boolean isTouchPointInView(float x, float y, ViewGroup parent, View child) {
float localX = x + parent.getScrollX() - child.getLeft();
float localY = y + parent.getScrollY() - child.getTop();
// Taken from {@link View#pointInView()}.
return localX >= 0 && localX < (child.getRight() - child.getLeft())
&& localY >= 0 && localY < (child.getBottom() - child.getTop());
} }
/** /**

View File

@ -385,8 +385,8 @@ public class UIViewOperationQueue {
final int touchTargetReactTag = mNativeViewHierarchyManager.findTargetTagForTouch( final int touchTargetReactTag = mNativeViewHierarchyManager.findTargetTagForTouch(
mReactTag, mReactTag,
mTargetX + containerX, mTargetX,
mTargetY + containerY); mTargetY);
try { try {
mNativeViewHierarchyManager.measure( mNativeViewHierarchyManager.measure(