Skip to content

Commit

Permalink
Fix incorrect hitState when non-React views are hit
Browse files Browse the repository at this point in the history
Summary: Changelog: [Android][Changed] Improved logic of findTargetPathAndCoordinatesForTouch

Reviewed By: Guad

Differential Revision: D31688645

fbshipit-source-id: b9ba91e135b6359e49998a314bf6c91a67fae5ed
  • Loading branch information
javache authored and facebook-github-bot committed Oct 18, 2021
1 parent 61755ac commit dfe42d6
Showing 1 changed file with 18 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

package com.facebook.react.uimanager;

import android.annotation.SuppressLint;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.Rect;
Expand Down Expand Up @@ -107,6 +108,7 @@ public static int findTargetTagAndCoordinatesForTouch(
* @return If a target was found, returns a path through the view tree of all react tags that are
* a container for the touch target, ordered from target to root (last element)
*/
@SuppressLint("ResourceType")
public static List<Integer> findTargetPathAndCoordinatesForTouch(
float eventX, float eventY, ViewGroup viewGroup, float[] viewCoords) {
UiThreadUtil.assertOnUiThread();
Expand All @@ -119,16 +121,29 @@ public static List<Integer> findTargetPathAndCoordinatesForTouch(
View targetView = findTouchTargetViewWithPointerEvents(viewCoords, viewGroup, pathAccumulator);

if (targetView != null) {
View reactTargetView = findClosestReactAncestor(targetView);
int targetTag = getTouchTargetForView(reactTargetView, viewCoords[0], viewCoords[1]);
if (targetTag != pathAccumulator.get(0)) {
View reactTargetView = targetView;
int firstReactAncestor = 0;
// Same logic as findClosestReactAncestor but also track the index
while (reactTargetView != null && reactTargetView.getId() <= 0) {
reactTargetView = (View) reactTargetView.getParent();
firstReactAncestor++;
}

if (firstReactAncestor > 0) {
// Drop non-React views from the path trace
pathAccumulator = pathAccumulator.subList(firstReactAncestor, pathAccumulator.size());
}

int targetTag = getTouchTargetForView(reactTargetView, eventX, eventY);
if (targetTag != reactTargetView.getId()) {
pathAccumulator.add(0, targetTag);
}
}

return pathAccumulator;
}

@SuppressLint("ResourceType")
private static View findClosestReactAncestor(View view) {
while (view != null && view.getId() <= 0) {
view = (View) view.getParent();
Expand Down

0 comments on commit dfe42d6

Please sign in to comment.