Fix touch target for views with z-index

Summary:
The new implementation of z-index did not handle touches properly. This fixes it by using the mapped child index like we do in `getChildDrawingOrder` in `TouchTargetHelper`.

**Test plan**
Tested that touchables work properly inside sticky headers (it uses z-index) on Android.
Closes https://github.com/facebook/react-native/pull/13705

Reviewed By: AaaChiuuu

Differential Revision: D4987964

Pulled By: sahrens

fbshipit-source-id: 165f98e23d2f304c4dc87f536c22b68a8923d806
This commit is contained in:
Janic Duplessis 2017-05-02 15:49:07 -07:00 committed by Facebook Github Bot
parent 70632615f3
commit 6f092a4264
3 changed files with 33 additions and 2 deletions

View File

@ -0,0 +1,15 @@
// Copyright 2004-present Facebook. All Rights Reserved.
package com.facebook.react.uimanager;
/**
* ViewGroup that supports z-index.
*/
public interface ReactZIndexedViewGroup {
/**
* Determine the index of a child view at {@param index} considering z-index.
* @param index The child view index
* @return The child view index considering z-index
*/
int getZIndexMappedChildIndex(int index);
}

View File

@ -124,8 +124,13 @@ public class TouchTargetHelper {
*/
private static View findTouchTargetView(float[] eventCoords, ViewGroup viewGroup) {
int childrenCount = viewGroup.getChildCount();
// Consider z-index when determining the touch target.
ReactZIndexedViewGroup zIndexedViewGroup = viewGroup instanceof ReactZIndexedViewGroup ?
(ReactZIndexedViewGroup) viewGroup :
null;
for (int i = childrenCount - 1; i >= 0; i--) {
View child = viewGroup.getChildAt(i);
int childIndex = zIndexedViewGroup != null ? zIndexedViewGroup.getZIndexMappedChildIndex(i) : i;
View child = viewGroup.getChildAt(childIndex);
PointF childPoint = mTempPoint;
if (isTransformedTouchPointInView(eventCoords[0], eventCoords[1], viewGroup, child, childPoint)) {
// If it is contained within the child View, the childPoint value will contain the view

View File

@ -31,6 +31,7 @@ import com.facebook.react.uimanager.PointerEvents;
import com.facebook.react.uimanager.ReactClippingViewGroup;
import com.facebook.react.uimanager.ReactClippingViewGroupHelper;
import com.facebook.react.uimanager.ReactPointerEventsView;
import com.facebook.react.uimanager.ReactZIndexedViewGroup;
import com.facebook.react.uimanager.ViewGroupDrawingOrderHelper;
/**
@ -38,7 +39,8 @@ import com.facebook.react.uimanager.ViewGroupDrawingOrderHelper;
* initializes most of the storage needed for them.
*/
public class ReactViewGroup extends ViewGroup implements
ReactInterceptingViewGroup, ReactClippingViewGroup, ReactPointerEventsView, ReactHitSlopView {
ReactInterceptingViewGroup, ReactClippingViewGroup, ReactPointerEventsView, ReactHitSlopView,
ReactZIndexedViewGroup {
private static final int ARRAY_CAPACITY_INCREMENT = 12;
private static final int DEFAULT_BACKGROUND_COLOR = Color.TRANSPARENT;
@ -408,6 +410,15 @@ public class ReactViewGroup extends ViewGroup implements
return mDrawingOrderHelper.getChildDrawingOrder(childCount, index);
}
@Override
public int getZIndexMappedChildIndex(int index) {
if (mDrawingOrderHelper.shouldEnableCustomDrawingOrder()) {
return mDrawingOrderHelper.getChildDrawingOrder(getChildCount(), index);
} else {
return index;
}
}
@Override
public PointerEvents getPointerEvents() {
return mPointerEvents;