mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Change touch target lookup to exclude overflow hidden view group
Summary: In D30104853 (https://github.com/facebook/react-native/commit/e35a963bfb93bbbdd92f4dd74d14e2ad6df5e14a), we added fix to the issue where touches on the child view that is outside of its parent view's boundary are not registered. The only exception to that is if the parent view has overflow style `overflow: hidden`. In that case, touches happen outside of the parent view should be ignored. {F686521911} That fix works, but it increases the complexity for the DFS algorithm used to find the touch target in two ways: 1. Before we only traverse views that contain the touch event point. If the touch event point is outside of the view, we won't step in and traverse that part of the tree. This is actually what caused the initial problem. The fix removed that boundary check (where `isTransformedTouchPointInView` used to do) and push it later. This increases the number of tree traversal a lot. 2. The check for `overflow: hidden` is happened after we find a potential target view, which means we've spent time to find the target view before we decide if the target view is even a candidate. This diff aims to update for the #2 item above. Since we are checking the style of the parent view, not the target view, it's not necessary to check that after we find the target view. We could check the parent view and if it has `overflow: hidden` on it, any pointer event that are not in the boundary can be ignored already. Changelog: [Internal][Android] Reviewed By: mdvacca, ShikaSD Differential Revision: D33079157 fbshipit-source-id: c79c2b38b8affb9ea0fd25b5e880b22466ab7ed9
This commit is contained in:
committed by
Facebook GitHub Bot
parent
41cad354e5
commit
0bd09c046a
@@ -178,6 +178,16 @@ public class TouchTargetHelper {
|
||||
// We prefer returning a child, so we check for a child that can handle the touch first
|
||||
if (allowReturnTouchTargetTypes.contains(TouchTargetReturnType.CHILD)
|
||||
&& view instanceof ViewGroup) {
|
||||
// We don't allow touches on views that are outside the bounds of an `overflow: hidden` and
|
||||
// `overflow: scroll` View.
|
||||
if (view instanceof ReactOverflowView) {
|
||||
@Nullable String overflow = ((ReactOverflowView) view).getOverflow();
|
||||
if ((ViewProps.HIDDEN.equals(overflow) || ViewProps.SCROLL.equals(overflow))
|
||||
&& !isTouchPointInView(eventCoords[0], eventCoords[1], view)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
ViewGroup viewGroup = (ViewGroup) view;
|
||||
int childrenCount = viewGroup.getChildCount();
|
||||
// Consider z-index when determining the touch target.
|
||||
@@ -198,22 +208,7 @@ public class TouchTargetHelper {
|
||||
eventCoords[1] = childPoint.y;
|
||||
View targetView = findTouchTargetViewWithPointerEvents(eventCoords, child, pathAccumulator);
|
||||
if (targetView != null) {
|
||||
// We don't allow touches on views that are outside the bounds of an `overflow: hidden`
|
||||
// View
|
||||
boolean inOverflowBounds = true;
|
||||
if (viewGroup instanceof ReactOverflowView) {
|
||||
@Nullable String overflow = ((ReactOverflowView) viewGroup).getOverflow();
|
||||
if ((ViewProps.HIDDEN.equals(overflow) || ViewProps.SCROLL.equals(overflow))
|
||||
&& !isTouchPointInView(restoreX, restoreY, view)) {
|
||||
inOverflowBounds = false;
|
||||
}
|
||||
}
|
||||
if (inOverflowBounds) {
|
||||
return targetView;
|
||||
} else if (pathAccumulator != null) {
|
||||
// Not a hit, reset the path found so far
|
||||
pathAccumulator.clear();
|
||||
}
|
||||
return targetView;
|
||||
}
|
||||
eventCoords[0] = restoreX;
|
||||
eventCoords[1] = restoreY;
|
||||
|
||||
Reference in New Issue
Block a user