From c9cae37ce48e8e864e35967a7fcaeffdd995a92f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Cargo=C3=ABt?= Date: Mon, 17 Jun 2019 09:28:16 +0200 Subject: [PATCH 1/3] Fixed android bounding box --- .../uimanager/NativeViewHierarchyManager.java | 46 ++++++++++++++++--- 1 file changed, 40 insertions(+), 6 deletions(-) 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..df33a8e13d785d 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); + void computeBoundingBox(View v, int[] outputBuffer) { + mBoundingBox.set(0, 0, v.getWidth(), v.getHeight()); + mapRectFromViewToWindowCoords(v, mBoundingBox); - outputBuffer[0] = outputBuffer[0] - rootX; - outputBuffer[1] = outputBuffer[1] - rootY; - outputBuffer[2] = v.getWidth(); - outputBuffer[3] = v.getHeight(); + outputBuffer[0] = (int) mBoundingBox.left; + outputBuffer[1] = (int) mBoundingBox.top; + outputBuffer[2] = (int) (mBoundingBox.right - mBoundingBox.left); + outputBuffer[3] = (int) (mBoundingBox.bottom - mBoundingBox.top); + } + + // simplified version of the hidden Android method View.mapRectFromViewToScreenCoords() + void mapRectFromViewToWindowCoords(View v, RectF rect) { + Matrix m = v.getMatrix(); + if (!m.isIdentity()) { + m.mapRect(rect); + } + + rect.offset(v.getLeft(), v.getTop()); + + ViewParent parent = v.getParent(); + while (parent instanceof View) { + View parentView = (View) parent; + + rect.offset(-parentView.getScrollX(), -parentView.getScrollY()); + m = parentView.getMatrix(); + if (!m.isIdentity()) { + m.mapRect(rect); + } + + rect.offset(parentView.getLeft(), parentView.getTop()); + + parent = parentView.getParent(); + } } /** From 2a6dee3cfab1f3b5d1e15e9ed4e7f76a441daad3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Cargo=C3=ABt?= Date: Sun, 28 Jul 2019 17:06:49 +0200 Subject: [PATCH 2/3] Applied changes requested by @mdvacca --- .../react/uimanager/NativeViewHierarchyManager.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) 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 df33a8e13d785d..f5832b2f2e4594 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java @@ -660,18 +660,18 @@ public synchronized void measure(int tag, int[] outputBuffer) { outputBuffer[1] -= rootY; } - void computeBoundingBox(View v, int[] outputBuffer) { + private void computeBoundingBox(View v, int[] outputBuffer) { mBoundingBox.set(0, 0, v.getWidth(), v.getHeight()); mapRectFromViewToWindowCoords(v, mBoundingBox); - outputBuffer[0] = (int) mBoundingBox.left; - outputBuffer[1] = (int) mBoundingBox.top; - outputBuffer[2] = (int) (mBoundingBox.right - mBoundingBox.left); - outputBuffer[3] = (int) (mBoundingBox.bottom - mBoundingBox.top); + 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); } // simplified version of the hidden Android method View.mapRectFromViewToScreenCoords() - void mapRectFromViewToWindowCoords(View v, RectF rect) { + private void mapRectFromViewToWindowCoords(View v, RectF rect) { Matrix m = v.getMatrix(); if (!m.isIdentity()) { m.mapRect(rect); From 1f441d033abf38005f46d90d1fb3b88c66d0a09c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Cargo=C3=ABt?= Date: Fri, 2 Aug 2019 12:59:09 +0200 Subject: [PATCH 3/3] added javadoc --- .../uimanager/NativeViewHierarchyManager.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) 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 f5832b2f2e4594..a59fbd25b7bcd7 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java @@ -660,6 +660,12 @@ public synchronized void measure(int tag, int[] outputBuffer) { outputBuffer[1] -= rootY; } + /** + * Fills the outputBuffer with the view's bounding box [x, y, width, height] + * + * @param v + * @param outputBuffer + */ private void computeBoundingBox(View v, int[] outputBuffer) { mBoundingBox.set(0, 0, v.getWidth(), v.getHeight()); mapRectFromViewToWindowCoords(v, mBoundingBox); @@ -670,7 +676,14 @@ private void computeBoundingBox(View v, int[] outputBuffer) { outputBuffer[3] = Math.round(mBoundingBox.bottom - mBoundingBox.top); } - // simplified version of the hidden Android method View.mapRectFromViewToScreenCoords() + /** + * Map a rectangle from view-relative coordinates to root-view-relative coordinates. + * This is a simplified version of the hidden Android method View.mapRectFromViewToScreenCoords() + * @see {@link View#mapRectFromViewToScreenCoords} + * + * @param v The view the coordinates are relative to + * @param rect The rectangle to be mapped + */ private void mapRectFromViewToWindowCoords(View v, RectF rect) { Matrix m = v.getMatrix(); if (!m.isIdentity()) {