Fix measureInWindow when using Nodes

Summary:
The results from measureInWindow were always wrong the first time it
was called. This was due to the fact that the view in question was not
actually a view yet, so the results were incorrect. This patch uses the
existing measure functionality (which can measure virtual nodes) to measure
the view, while modifying it to properly get the results relative to the
window instead of relative to the root view.

Reviewed By: sriramramani

Differential Revision: D3501544
This commit is contained in:
Ahmed El-Helw 2016-06-30 17:03:23 -07:00
parent ace1b4d78e
commit 9a28701bd8
2 changed files with 23 additions and 4 deletions

View File

@ -182,6 +182,10 @@ public class FlatUIImplementation extends UIImplementation {
@Override
public void measure(int reactTag, Callback callback) {
measureHelper(reactTag, false, callback);
}
private void measureHelper(int reactTag, boolean relativeToWindow, Callback callback) {
FlatShadowNode node = (FlatShadowNode) resolveShadowNode(reactTag);
if (node.mountsToView()) {
mStateBuilder.ensureBackingViewIsCreated(node);
@ -216,6 +220,7 @@ public class FlatUIImplementation extends UIImplementation {
yInParent / parentHeight,
width / parentWidth,
height / parentHeight,
relativeToWindow,
callback);
}
@ -235,8 +240,7 @@ public class FlatUIImplementation extends UIImplementation {
@Override
public void measureInWindow(int reactTag, Callback callback) {
ensureMountsToViewAndBackingViewIsCreated(reactTag);
super.measureInWindow(reactTag, callback);
measureHelper(reactTag, true, callback);
}
@Override

View File

@ -173,6 +173,7 @@ import com.facebook.react.uimanager.UIViewOperationQueue;
private final float mScaledWidth;
private final float mScaledHeight;
private final Callback mCallback;
private final boolean mRelativeToWindow;
private MeasureVirtualView(
int reactTag,
@ -180,6 +181,7 @@ import com.facebook.react.uimanager.UIViewOperationQueue;
float scaledY,
float scaledWidth,
float scaledHeight,
boolean relativeToWindow,
Callback callback) {
mReactTag = reactTag;
mScaledX = scaledX;
@ -187,13 +189,20 @@ import com.facebook.react.uimanager.UIViewOperationQueue;
mScaledWidth = scaledWidth;
mScaledHeight = scaledHeight;
mCallback = callback;
mRelativeToWindow = relativeToWindow;
}
@Override
public void execute() {
try {
// Measure native View
mNativeViewHierarchyManager.measure(mReactTag, MEASURE_BUFFER);
if (mRelativeToWindow) {
// relative to the window
mNativeViewHierarchyManager.measureInWindow(mReactTag, MEASURE_BUFFER);
} else {
// relative to the root view
mNativeViewHierarchyManager.measure(mReactTag, MEASURE_BUFFER);
}
} catch (NoSuchNativeViewException noSuchNativeViewException) {
// Invoke with no args to signal failure and to allow JS to clean up the callback
// handle.
@ -212,7 +221,11 @@ import com.facebook.react.uimanager.UIViewOperationQueue;
float width = PixelUtil.toDIPFromPixel(mScaledWidth * nativeViewWidth);
float height = PixelUtil.toDIPFromPixel(mScaledHeight * nativeViewHeight);
mCallback.invoke(0, 0, width, height, x, y);
if (mRelativeToWindow) {
mCallback.invoke(x, y, width, height);
} else {
mCallback.invoke(0, 0, width, height, x, y);
}
}
}
@ -366,6 +379,7 @@ import com.facebook.react.uimanager.UIViewOperationQueue;
float scaledY,
float scaledWidth,
float scaledHeight,
boolean relativeToWindow,
Callback callback) {
enqueueUIOperation(new MeasureVirtualView(
reactTag,
@ -373,6 +387,7 @@ import com.facebook.react.uimanager.UIViewOperationQueue;
scaledY,
scaledWidth,
scaledHeight,
relativeToWindow,
callback));
}