diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactCompoundViewGroup.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactCompoundViewGroup.java new file mode 100644 index 000000000..345dea9f9 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactCompoundViewGroup.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.facebook.react.uimanager; + +/** + * This interface should be implemented be native ViewGroup subclasses that can represent more + * than a single react node. In that case, virtual and non-virtual (mapping to a View) elements + * can overlap, and TouchTargetHelper may incorrectly dispatch touch event to a wrong element + * because it priorities children over parents. + */ +public interface ReactCompoundViewGroup extends ReactCompoundView { + /** + * Returns true if react node responsible for the touch even is flattened into this ViewGroup. + * Use reactTagForTouch() to get its tag. + */ + boolean interceptsTouchEvent(float touchX, float touchY); +} 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 e998110b7..8c74639d5 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/TouchTargetHelper.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/TouchTargetHelper.java @@ -209,6 +209,11 @@ public class TouchTargetHelper { } else if (pointerEvents == PointerEvents.AUTO) { // Either this view or one of its children is the target + if (view instanceof ReactCompoundViewGroup) { + if (((ReactCompoundViewGroup) view).interceptsTouchEvent(eventCoords[0], eventCoords[1])) { + return view; + } + } if (view instanceof ViewGroup) { return findTouchTargetView(eventCoords, (ViewGroup) view); }