diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java index 5116111f92745f..bf4908c7c0611e 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java @@ -7,6 +7,8 @@ package com.facebook.react.uimanager; import android.content.res.Resources; +import android.graphics.Matrix; +import android.graphics.RectF; import android.util.SparseArray; import android.util.SparseBooleanArray; import android.util.SparseIntArray; @@ -74,6 +76,7 @@ public class NativeViewHierarchyManager { private final LayoutAnimationController mLayoutAnimator = new LayoutAnimationController(); private final SparseArray mTagsToPendingIndicesToDelete = new SparseArray<>(); private final int[] mDroppedViewArray = new int[100]; + private final RectF mBoundingBox = new RectF(); private boolean mLayoutAnimationEnabled; private PopupMenu mPopupMenu; @@ -649,16 +652,47 @@ public synchronized void measure(int tag, int[] outputBuffer) { if (rootView == null) { throw new NoSuchNativeViewException("Native view " + tag + " is no longer on screen"); } - rootView.getLocationInWindow(outputBuffer); + computeBoundingBox(rootView, outputBuffer); int rootX = outputBuffer[0]; int rootY = outputBuffer[1]; + computeBoundingBox(v, outputBuffer); + outputBuffer[0] -= rootX; + outputBuffer[1] -= rootY; + } - v.getLocationInWindow(outputBuffer); + private void computeBoundingBox(View view, int[] outputBuffer) { + mBoundingBox.set(0, 0, view.getWidth(), view.getHeight()); + mapRectFromViewToWindowCoords(view, mBoundingBox); - outputBuffer[0] = outputBuffer[0] - rootX; - outputBuffer[1] = outputBuffer[1] - rootY; - outputBuffer[2] = v.getWidth(); - outputBuffer[3] = v.getHeight(); + outputBuffer[0] = Math.round(mBoundingBox.left); + outputBuffer[1] = Math.round(mBoundingBox.top); + outputBuffer[2] = Math.round(mBoundingBox.right - mBoundingBox.left); + outputBuffer[3] = Math.round(mBoundingBox.bottom - mBoundingBox.top); + } + + private void mapRectFromViewToWindowCoords(View view, RectF rect) { + Matrix matrix = view.getMatrix(); + if (!matrix.isIdentity()) { + matrix.mapRect(rect); + } + + rect.offset(view.getLeft(), view.getTop()); + + ViewParent parent = view.getParent(); + while (parent instanceof View) { + View parentView = (View) parent; + + rect.offset(-parentView.getScrollX(), -parentView.getScrollY()); + + matrix = parentView.getMatrix(); + if (!matrix.isIdentity()) { + matrix.mapRect(rect); + } + + rect.offset(parentView.getLeft(), parentView.getTop()); + + parent = parentView.getParent(); + } } /**