Update/Add NodeRegion after collectState()

Summary: RCTText may modify its DrawCommand on collectState(), which updateNodeRegion() relies on. This means that order of the two is important: call collectState() first, followed by updateNodeRegion(). This fixes the bug where am RCTText may sometimes not respond to clicks (because its NodeRegion would be empty).

Reviewed By: ahmedre

Differential Revision: D2816295
This commit is contained in:
Denis Koroskin 2016-01-11 20:03:20 -08:00 committed by Ahmed El-Helw
parent e7d8d2c3ab
commit 584cbd3b99
1 changed files with 18 additions and 28 deletions

View File

@ -83,8 +83,6 @@ import com.facebook.react.uimanager.events.EventDispatcher;
Float.POSITIVE_INFINITY,
Float.POSITIVE_INFINITY);
node.updateNodeRegion(left, top, right, bottom);
updateViewBounds(node, left, top, right, bottom);
if (mDetachAllChildrenFromViews != null) {
@ -146,8 +144,14 @@ import com.facebook.react.uimanager.events.EventDispatcher;
mViewsToDrop.add(node);
}
private void addNodeRegion(NodeRegion nodeRegion) {
mNodeRegions.add(nodeRegion);
private void addNodeRegion(
FlatShadowNode node,
float left,
float top,
float right,
float bottom) {
node.updateNodeRegion(left, top, right, bottom);
mNodeRegions.add(node.getNodeRegion());
}
private void addNativeChild(FlatShadowNode nativeChild) {
@ -216,13 +220,6 @@ import com.facebook.react.uimanager.events.EventDispatcher;
clipTop = Float.NEGATIVE_INFINITY;
clipRight = Float.POSITIVE_INFINITY;
clipBottom = Float.POSITIVE_INFINITY;
} else if (node.isVirtualAnchor()) {
// If RCTText is mounted to View, virtual children will not receive any touch events
// because they don't get added to nodeRegions, so nodeRegions will be empty and
// 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.getNodeRegion());
}
collectStateRecursively(
@ -238,6 +235,15 @@ import com.facebook.react.uimanager.events.EventDispatcher;
isAndroidView,
needsCustomLayoutForChildren);
if (node.isVirtualAnchor()) {
// If RCTText is mounted to View, virtual children will not receive any touch events
// because they don't get added to nodeRegions, so nodeRegions will be empty and
// 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);
}
boolean shouldUpdateMountState = false;
final DrawCommand[] drawCommands = mDrawCommands.finish();
if (drawCommands != null) {
@ -424,8 +430,6 @@ import com.facebook.react.uimanager.events.EventDispatcher;
float right = left + width;
float bottom = top + height;
node.updateNodeRegion(left, top, right, bottom);
if (node.mountsToView()) {
ensureBackingViewIsCreated(node, tag, null);
@ -466,21 +470,7 @@ import com.facebook.react.uimanager.events.EventDispatcher;
parentClipBottom,
false,
false);
addNodeRegion(node.getNodeRegion());
}
}
private static void updateNodeRegion(
FlatShadowNode node,
int tag,
float left,
float top,
float right,
float bottom) {
final NodeRegion nodeRegion = node.getNodeRegion();
if (nodeRegion.mLeft != left || nodeRegion.mTop != top ||
nodeRegion.mRight != right || nodeRegion.mBottom != bottom) {
node.setNodeRegion(new NodeRegion(left, top, right, bottom, tag));
addNodeRegion(node, left, top, right, bottom);
}
}