mirror of
https://github.com/status-im/react-native.git
synced 2025-02-27 00:20:31 +00:00
Fix touch inspector when using Nodes
Summary: Fix touch inspector when using Nodes by implementing custom logic. This logic now takes into account that non-View nodes need to be clickable. Reviewed By: astreet Differential Revision: D3433927
This commit is contained in:
parent
5f3f9caceb
commit
4ecfa0c800
@ -12,11 +12,15 @@ package com.facebook.react.flat;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.facebook.react.bridge.Callback;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.uimanager.IllegalViewOperationException;
|
||||
import com.facebook.react.uimanager.NoSuchNativeViewException;
|
||||
import com.facebook.react.uimanager.PixelUtil;
|
||||
import com.facebook.react.uimanager.TouchTargetHelper;
|
||||
import com.facebook.react.uimanager.UIViewOperationQueue;
|
||||
|
||||
/**
|
||||
@ -225,6 +229,78 @@ import com.facebook.react.uimanager.UIViewOperationQueue;
|
||||
}
|
||||
}
|
||||
|
||||
private final class FindTargetForTouchOperation implements UIOperation {
|
||||
|
||||
private final int mReactTag;
|
||||
private final float mTargetX;
|
||||
private final float mTargetY;
|
||||
private final Callback mCallback;
|
||||
private final int[] NATIVE_VIEW_BUFFER = new int[1];
|
||||
|
||||
private FindTargetForTouchOperation(
|
||||
final int reactTag,
|
||||
final float targetX,
|
||||
final float targetY,
|
||||
final Callback callback) {
|
||||
super();
|
||||
mReactTag = reactTag;
|
||||
mTargetX = targetX;
|
||||
mTargetY = targetY;
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
try {
|
||||
mNativeViewHierarchyManager.measure(mReactTag, MEASURE_BUFFER);
|
||||
} catch (IllegalViewOperationException e) {
|
||||
mCallback.invoke();
|
||||
return;
|
||||
}
|
||||
|
||||
// Because React coordinates are relative to root container, and measure() operates
|
||||
// on screen coordinates, we need to offset values using root container location.
|
||||
final float containerX = (float) MEASURE_BUFFER[0];
|
||||
final float containerY = (float) MEASURE_BUFFER[1];
|
||||
|
||||
View view = mNativeViewHierarchyManager.getView(mReactTag);
|
||||
final int touchTargetReactTag = TouchTargetHelper.findTargetTagForTouch(
|
||||
mTargetX,
|
||||
mTargetY,
|
||||
(ViewGroup) view,
|
||||
NATIVE_VIEW_BUFFER);
|
||||
|
||||
try {
|
||||
mNativeViewHierarchyManager.measure(
|
||||
NATIVE_VIEW_BUFFER[0],
|
||||
MEASURE_BUFFER);
|
||||
} catch (IllegalViewOperationException e) {
|
||||
mCallback.invoke();
|
||||
return;
|
||||
}
|
||||
|
||||
NodeRegion region = NodeRegion.EMPTY;
|
||||
boolean isNativeView = NATIVE_VIEW_BUFFER[0] == touchTargetReactTag;
|
||||
if (!isNativeView) {
|
||||
// NATIVE_VIEW_BUFFER[0] is a FlatViewGroup, touchTargetReactTag is the touch target and
|
||||
// isn't an Android View - try to get its NodeRegion
|
||||
view = mNativeViewHierarchyManager.getView(NATIVE_VIEW_BUFFER[0]);
|
||||
if (view instanceof FlatViewGroup) {
|
||||
region = ((FlatViewGroup) view).getNodeRegionForTag(mReactTag);
|
||||
}
|
||||
}
|
||||
|
||||
int resultTag = region == NodeRegion.EMPTY ? touchTargetReactTag : region.mTag;
|
||||
float x = PixelUtil.toDIPFromPixel(region.mLeft + MEASURE_BUFFER[0] - containerX);
|
||||
float y = PixelUtil.toDIPFromPixel(region.mTop + MEASURE_BUFFER[1] - containerY);
|
||||
float width = PixelUtil.toDIPFromPixel(isNativeView ?
|
||||
MEASURE_BUFFER[2] : region.mRight - region.mLeft);
|
||||
float height = PixelUtil.toDIPFromPixel(isNativeView ?
|
||||
MEASURE_BUFFER[3] : region.mBottom - region.mTop);
|
||||
mCallback.invoke(resultTag, x, y, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
public FlatUIViewOperationQueue(
|
||||
ReactApplicationContext reactContext,
|
||||
FlatNativeViewHierarchyManager nativeViewHierarchyManager) {
|
||||
@ -309,4 +385,14 @@ import com.facebook.react.uimanager.UIViewOperationQueue;
|
||||
enqueueUIOperation(op);
|
||||
return op;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enqueueFindTargetForTouch(
|
||||
final int reactTag,
|
||||
final float targetX,
|
||||
final float targetY,
|
||||
final Callback callback) {
|
||||
enqueueUIOperation(
|
||||
new FindTargetForTouchOperation(reactTag, targetX, targetY, callback));
|
||||
}
|
||||
}
|
||||
|
@ -410,6 +410,20 @@ import com.facebook.react.views.view.ReactClippingViewGroupHelper;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a NodeRegion which matches the said reactTag
|
||||
* @param reactTag the reactTag to look for
|
||||
* @return the NodeRegion, or NodeRegion.EMPTY
|
||||
*/
|
||||
/* package */ NodeRegion getNodeRegionForTag(int reactTag) {
|
||||
for (NodeRegion region : mNodeRegions) {
|
||||
if (region.matchesTag(reactTag)) {
|
||||
return region;
|
||||
}
|
||||
}
|
||||
return NodeRegion.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of FlatViewGroups that are detached (due to being clipped) but that we have a
|
||||
* strong reference to. This is used by the FlatNativeViewHierarchyManager to explicitly clean up
|
||||
|
@ -42,4 +42,8 @@ package com.facebook.react.flat;
|
||||
/* package */ int getReactTag(float touchX, float touchY) {
|
||||
return mTag;
|
||||
}
|
||||
|
||||
/* package */ boolean matchesTag(int tag) {
|
||||
return mTag == tag;
|
||||
}
|
||||
}
|
||||
|
@ -59,4 +59,22 @@ import android.text.Spanned;
|
||||
|
||||
return super.getReactTag(touchX, touchY);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean matchesTag(int tag) {
|
||||
if (super.matchesTag(tag)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mLayout != null) {
|
||||
Spanned text = (Spanned) mLayout.getText();
|
||||
RCTRawText[] spans = text.getSpans(0, text.length(), RCTRawText.class);
|
||||
for (RCTRawText span : spans) {
|
||||
if (span.getReactTag() == tag) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user