Include non-virtual nodes when collecting NodeRegions
Summary: Before this patch, we only collected virtual nodes in NodeRegions, because NodeRegions are only needed to implement ReactCompoundView.reactTargetForTouch() which is only interested in virtual nodes. In the next patch, FlatViewGroup will implement ReactCompoundViewGroup interface which requires knowledge of both virtual and non-virtual children. As a step towards that, we need to include non-virtual nodes in NodeRegions. This patch is implementing that. By itself, it should have not cause any changes in application behavior: we add non-virtual nodes to NodeRegions and mark them as non-virtual, then skip all non-virtual nodes in reactTagForTouch(). Reviewed By: ahmedre Differential Revision: D3018047
This commit is contained in:
parent
8014147013
commit
b52928c484
|
@ -251,10 +251,15 @@ import com.facebook.react.uimanager.annotations.ReactProp;
|
|||
mNodeRegions = nodeRegion;
|
||||
}
|
||||
|
||||
/* package */ void updateNodeRegion(float left, float top, float right, float bottom) {
|
||||
if (mNodeRegion.mLeft != left || mNodeRegion.mTop != top ||
|
||||
mNodeRegion.mRight != right || mNodeRegion.mBottom != bottom) {
|
||||
setNodeRegion(new NodeRegion(left, top, right, bottom, getReactTag()));
|
||||
/* package */ void updateNodeRegion(
|
||||
float left,
|
||||
float top,
|
||||
float right,
|
||||
float bottom,
|
||||
boolean isVirtual) {
|
||||
if (mNodeRegion.mLeft != left || mNodeRegion.mTop != top || mNodeRegion.mRight != right ||
|
||||
mNodeRegion.mBottom != bottom || mNodeRegion.mIsVirtual != isVirtual) {
|
||||
setNodeRegion(new NodeRegion(left, top, right, bottom, getReactTag(), isVirtual));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ import com.facebook.react.views.image.ImageLoadEvent;
|
|||
"TouchTargetHelper should not allow calling this method when pointer events are NONE");
|
||||
|
||||
if (mPointerEvents != PointerEvents.BOX_ONLY) {
|
||||
NodeRegion nodeRegion = nodeRegionWithinBounds(touchX, touchY);
|
||||
NodeRegion nodeRegion = virtualNodeRegionWithinBounds(touchX, touchY);
|
||||
if (nodeRegion != null) {
|
||||
return nodeRegion.getReactTag(touchX, touchY);
|
||||
}
|
||||
|
@ -277,7 +277,7 @@ import com.facebook.react.views.image.ImageLoadEvent;
|
|||
|
||||
if (mPointerEvents == PointerEvents.BOX_NONE) {
|
||||
// We cannot always return false here because some child nodes could be flatten into this View
|
||||
NodeRegion nodeRegion = nodeRegionWithinBounds(ev.getX(), ev.getY());
|
||||
NodeRegion nodeRegion = virtualNodeRegionWithinBounds(ev.getX(), ev.getY());
|
||||
if (nodeRegion == null) {
|
||||
// no child to handle this touch event, bailing out.
|
||||
return false;
|
||||
|
@ -411,9 +411,13 @@ import com.facebook.react.views.image.ImageLoadEvent;
|
|||
LAYOUT_REQUESTS.clear();
|
||||
}
|
||||
|
||||
private NodeRegion nodeRegionWithinBounds(float touchX, float touchY) {
|
||||
private NodeRegion virtualNodeRegionWithinBounds(float touchX, float touchY) {
|
||||
for (int i = mNodeRegions.length - 1; i >= 0; --i) {
|
||||
NodeRegion nodeRegion = mNodeRegions[i];
|
||||
if (!nodeRegion.mIsVirtual) {
|
||||
// only interested in virtual nodes
|
||||
continue;
|
||||
}
|
||||
if (nodeRegion.withinBounds(touchX, touchY)) {
|
||||
return nodeRegion;
|
||||
}
|
||||
|
|
|
@ -11,20 +11,28 @@ package com.facebook.react.flat;
|
|||
|
||||
/* package */ class NodeRegion {
|
||||
/* package */ static final NodeRegion[] EMPTY_ARRAY = new NodeRegion[0];
|
||||
/* package */ static final NodeRegion EMPTY = new NodeRegion(0, 0, 0, 0, -1);
|
||||
/* package */ static final NodeRegion EMPTY = new NodeRegion(0, 0, 0, 0, -1, false);
|
||||
|
||||
/* package */ final float mLeft;
|
||||
/* package */ final float mTop;
|
||||
/* package */ final float mRight;
|
||||
/* package */ final float mBottom;
|
||||
/* package */ final int mTag;
|
||||
/* package */ final boolean mIsVirtual;
|
||||
|
||||
/* package */ NodeRegion(float left, float top, float right, float bottom, int tag) {
|
||||
/* package */ NodeRegion(
|
||||
float left,
|
||||
float top,
|
||||
float right,
|
||||
float bottom,
|
||||
int tag,
|
||||
boolean isVirtual) {
|
||||
mLeft = left;
|
||||
mTop = top;
|
||||
mRight = right;
|
||||
mBottom = bottom;
|
||||
mTag = tag;
|
||||
mIsVirtual = isVirtual;
|
||||
}
|
||||
|
||||
/* package */ final boolean withinBounds(float touchX, float touchY) {
|
||||
|
|
|
@ -223,9 +223,14 @@ import com.facebook.react.uimanager.annotations.ReactProp;
|
|||
}
|
||||
|
||||
@Override
|
||||
/* package */ void updateNodeRegion(float left, float top, float right, float bottom) {
|
||||
/* package */ void updateNodeRegion(
|
||||
float left,
|
||||
float top,
|
||||
float right,
|
||||
float bottom,
|
||||
boolean isVirtual) {
|
||||
if (mDrawCommand == null) {
|
||||
super.updateNodeRegion(left, top, right, bottom);
|
||||
super.updateNodeRegion(left, top, right, bottom, isVirtual);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -239,8 +244,9 @@ import com.facebook.react.uimanager.annotations.ReactProp;
|
|||
Layout newLayout = mDrawCommand.getLayout();
|
||||
if (nodeRegion.mLeft != left || nodeRegion.mTop != top ||
|
||||
nodeRegion.mRight != right || nodeRegion.mBottom != bottom ||
|
||||
layout != newLayout) {
|
||||
setNodeRegion(new TextNodeRegion(left, top, right, bottom, getReactTag(), newLayout));
|
||||
nodeRegion.mIsVirtual != isVirtual || layout != newLayout) {
|
||||
setNodeRegion(
|
||||
new TextNodeRegion(left, top, right, bottom, getReactTag(), isVirtual, newLayout));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -197,13 +197,14 @@ import com.facebook.react.uimanager.events.EventDispatcher;
|
|||
float left,
|
||||
float top,
|
||||
float right,
|
||||
float bottom) {
|
||||
float bottom,
|
||||
boolean isVirtual) {
|
||||
if (left == right || top == bottom) {
|
||||
// no point in adding an empty NodeRegion
|
||||
return;
|
||||
}
|
||||
|
||||
node.updateNodeRegion(left, top, right, bottom);
|
||||
node.updateNodeRegion(left, top, right, bottom, isVirtual);
|
||||
mNodeRegions.add(node.getNodeRegion());
|
||||
}
|
||||
|
||||
|
@ -291,7 +292,7 @@ import com.facebook.react.uimanager.events.EventDispatcher;
|
|||
// FlatViewGroup.reactTagForTouch() will always return RCTText's id. To fix the issue,
|
||||
// manually add nodeRegion so it will have exactly one NodeRegion, and virtual nodes will
|
||||
// be able to receive touch events.
|
||||
addNodeRegion(node, left, top, right, bottom);
|
||||
addNodeRegion(node, left, top, right, bottom, true);
|
||||
}
|
||||
|
||||
boolean descendantUpdated = collectStateRecursively(
|
||||
|
@ -520,9 +521,15 @@ import com.facebook.react.uimanager.events.EventDispatcher;
|
|||
float right = left + width;
|
||||
float bottom = top + height;
|
||||
|
||||
boolean mountsToView = node.mountsToView();
|
||||
|
||||
final boolean updated;
|
||||
|
||||
if (node.mountsToView()) {
|
||||
if (!parentIsAndroidView) {
|
||||
addNodeRegion(node, left, top, right, bottom, !mountsToView);
|
||||
}
|
||||
|
||||
if (mountsToView) {
|
||||
ensureBackingViewIsCreated(node);
|
||||
|
||||
addNativeChild(node);
|
||||
|
@ -549,8 +556,6 @@ import com.facebook.react.uimanager.events.EventDispatcher;
|
|||
updateViewBounds(node, left, top, right, bottom);
|
||||
}
|
||||
} else {
|
||||
addNodeRegion(node, left, top, right, bottom);
|
||||
|
||||
updated = collectStateRecursively(
|
||||
node,
|
||||
left,
|
||||
|
|
|
@ -15,8 +15,15 @@ import android.text.Spanned;
|
|||
/* package */ final class TextNodeRegion extends NodeRegion {
|
||||
private final Layout mLayout;
|
||||
|
||||
TextNodeRegion(float left, float top, float right, float bottom, int tag, Layout layout) {
|
||||
super(left, top, right, bottom, tag);
|
||||
/* package */ TextNodeRegion(
|
||||
float left,
|
||||
float top,
|
||||
float right,
|
||||
float bottom,
|
||||
int tag,
|
||||
boolean isVirtual,
|
||||
Layout layout) {
|
||||
super(left, top, right, bottom, tag, isVirtual);
|
||||
mLayout = layout;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue