Summary: Before the patch, order of NodeRegions was inconsistent. Given parent A and 3 children B, C and D, we collect DrawCommands like this: A, B, C, D but NodeRegions were collected as B, C, D, A which neither matches draw order, nor a reverse of it. This patch changes it so that NodeRegions are collected in drawing order (A, B, C, D) and we iterate backwards to find correct touch target (in case they overlap).

Reviewed By: ahmedre

Differential Revision: D3018034
This commit is contained in:
Denis Koroskin 2016-03-07 20:06:30 -08:00 коммит произвёл Ahmed El-Helw
Родитель 4d25624a62
Коммит 8014147013
2 изменённых файлов: 13 добавлений и 11 удалений

Просмотреть файл

@ -412,7 +412,8 @@ import com.facebook.react.views.image.ImageLoadEvent;
}
private NodeRegion nodeRegionWithinBounds(float touchX, float touchY) {
for (NodeRegion nodeRegion : mNodeRegions) {
for (int i = mNodeRegions.length - 1; i >= 0; --i) {
NodeRegion nodeRegion = mNodeRegions[i];
if (nodeRegion.withinBounds(touchX, touchY)) {
return nodeRegion;
}

Просмотреть файл

@ -285,6 +285,15 @@ import com.facebook.react.uimanager.events.EventDispatcher;
clipBottom = Float.POSITIVE_INFINITY;
}
if (!isAndroidView && 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 descendantUpdated = collectStateRecursively(
node,
left,
@ -298,15 +307,6 @@ import com.facebook.react.uimanager.events.EventDispatcher;
isAndroidView,
needsCustomLayoutForChildren);
if (!isAndroidView && 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) {
@ -549,6 +549,8 @@ import com.facebook.react.uimanager.events.EventDispatcher;
updateViewBounds(node, left, top, right, bottom);
}
} else {
addNodeRegion(node, left, top, right, bottom);
updated = collectStateRecursively(
node,
left,
@ -561,7 +563,6 @@ import com.facebook.react.uimanager.events.EventDispatcher;
parentClipBottom,
false,
false);
addNodeRegion(node, left, top, right, bottom);
}
return updated;