mirror of
https://github.com/status-im/react-native.git
synced 2025-02-05 22:23:37 +00:00
Make FlatUIImplementation.measure() work with virtual views (shadow nodes that don't map to a View)
Summary: UIImplementation.measure() can only measure shadow nodes that map to native Views. As a result of this, every time we tried to measure a shadow node that doesn't map to a View, we trigger callback with no data (to indicate an error). To fix this issue, walk up until we find a node that maps to a View, then measure that View and adjust for the bounds of a virtual child. Reviewed By: ahmedre Differential Revision: D2800960
This commit is contained in:
parent
b321ea98d3
commit
05544f6bca
@ -16,6 +16,8 @@ import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import com.facebook.infer.annotation.Assertions;
|
||||
import com.facebook.react.bridge.Callback;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.uimanager.CatalystStylesDiffMap;
|
||||
@ -151,6 +153,43 @@ public class FlatUIImplementation extends UIImplementation {
|
||||
addChildren(parentNode, addChildTags, addAtIndices);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void measure(int reactTag, Callback callback) {
|
||||
FlatShadowNode node = (FlatShadowNode) resolveShadowNode(reactTag);
|
||||
if (node.mountsToView()) {
|
||||
super.measure(reactTag, callback);
|
||||
return;
|
||||
}
|
||||
|
||||
float width = node.getLayoutWidth();
|
||||
float height = node.getLayoutHeight();
|
||||
|
||||
float xInParent = node.getLayoutX();
|
||||
float yInParent = node.getLayoutY();
|
||||
|
||||
while (true) {
|
||||
node = Assertions.assumeNotNull((FlatShadowNode) node.getParent());
|
||||
if (node.mountsToView()) {
|
||||
break;
|
||||
}
|
||||
|
||||
xInParent += node.getLayoutX();
|
||||
yInParent += node.getLayoutY();
|
||||
}
|
||||
|
||||
float parentWidth = node.getLayoutWidth();
|
||||
float parentHeight = node.getLayoutHeight();
|
||||
|
||||
FlatUIViewOperationQueue operationsQueue = mStateBuilder.getOperationsQueue();
|
||||
operationsQueue.enqueueMeasureVirtualView(
|
||||
node.getReactTag(),
|
||||
xInParent / parentWidth,
|
||||
yInParent / parentHeight,
|
||||
width / parentWidth,
|
||||
height / parentHeight,
|
||||
callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all children defined by moveFrom and removeFrom from a given parent,
|
||||
* preparing elements in moveFrom to be re-added at proper index.
|
||||
|
@ -11,7 +11,9 @@ package com.facebook.react.flat;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.facebook.react.bridge.Callback;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.uimanager.PixelUtil;
|
||||
import com.facebook.react.uimanager.UIViewOperationQueue;
|
||||
|
||||
/**
|
||||
@ -20,6 +22,8 @@ import com.facebook.react.uimanager.UIViewOperationQueue;
|
||||
*/
|
||||
/* package */ final class FlatUIViewOperationQueue extends UIViewOperationQueue {
|
||||
|
||||
private static final int[] MEASURE_BUFFER = new int[4];
|
||||
|
||||
private final FlatNativeViewHierarchyManager mNativeViewHierarchyManager;
|
||||
private final ProcessLayoutRequests mProcessLayoutRequests = new ProcessLayoutRequests();
|
||||
|
||||
@ -150,6 +154,50 @@ import com.facebook.react.uimanager.UIViewOperationQueue;
|
||||
}
|
||||
}
|
||||
|
||||
private final class MeasureVirtualView implements UIOperation {
|
||||
|
||||
private final int mReactTag;
|
||||
private final float mScaledX;
|
||||
private final float mScaledY;
|
||||
private final float mScaledWidth;
|
||||
private final float mScaledHeight;
|
||||
private final Callback mCallback;
|
||||
|
||||
private MeasureVirtualView(
|
||||
int reactTag,
|
||||
float scaledX,
|
||||
float scaledY,
|
||||
float scaledWidth,
|
||||
float scaledHeight,
|
||||
Callback callback) {
|
||||
mReactTag = reactTag;
|
||||
mScaledX = scaledX;
|
||||
mScaledY = scaledY;
|
||||
mScaledWidth = scaledWidth;
|
||||
mScaledHeight = scaledHeight;
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
// Measure native View
|
||||
mNativeViewHierarchyManager.measure(mReactTag, MEASURE_BUFFER);
|
||||
|
||||
float nativeViewX = MEASURE_BUFFER[0];
|
||||
float nativeViewY = MEASURE_BUFFER[1];
|
||||
float nativeViewWidth = MEASURE_BUFFER[2];
|
||||
float nativeViewHeight = MEASURE_BUFFER[3];
|
||||
|
||||
// Calculate size of the virtual child inside native View.
|
||||
float x = PixelUtil.toDIPFromPixel(mScaledX * nativeViewWidth + nativeViewX);
|
||||
float y = PixelUtil.toDIPFromPixel(mScaledY * nativeViewHeight + nativeViewY);
|
||||
float width = PixelUtil.toDIPFromPixel(mScaledWidth * nativeViewWidth);
|
||||
float height = PixelUtil.toDIPFromPixel(mScaledHeight * nativeViewHeight);
|
||||
|
||||
mCallback.invoke(0, 0, width, height, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
public final class DetachAllChildrenFromViews implements UIViewOperationQueue.UIOperation {
|
||||
private @Nullable int[] mViewsToDetachAllChildrenFrom;
|
||||
|
||||
@ -207,6 +255,22 @@ import com.facebook.react.uimanager.UIViewOperationQueue;
|
||||
enqueueUIOperation(new DropViews(viewsToDrop));
|
||||
}
|
||||
|
||||
public void enqueueMeasureVirtualView(
|
||||
int reactTag,
|
||||
float scaledX,
|
||||
float scaledY,
|
||||
float scaledWidth,
|
||||
float scaledHeight,
|
||||
Callback callback) {
|
||||
enqueueUIOperation(new MeasureVirtualView(
|
||||
reactTag,
|
||||
scaledX,
|
||||
scaledY,
|
||||
scaledWidth,
|
||||
scaledHeight,
|
||||
callback));
|
||||
}
|
||||
|
||||
public void enqueueProcessLayoutRequests() {
|
||||
enqueueUIOperation(mProcessLayoutRequests);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user