Fixed android bounding box (#25836)
Summary: This PR fixes https://github.com/facebook/react-native/issues/19637. Summary of the issue: on Android, transformed touchables have press issues because the touchable's measurements are incorrect in the release phase. `UIManager.measure()` returns an incorrect size and position as explained [here](https://github.com/facebook/react-native/issues/19637#issuecomment-396065914) This is easily seen with the inspector : **Screenshot of a { scale: 2 } transform** The real view (scaled) is in pink, the incorrect touchable area is in blue. <img src="https://user-images.githubusercontent.com/110431/41190133-8d07ad02-6bd9-11e8-873d-93776a007309.png" width="200"/> **Screenshot of a { rotateZ: "-45deg" } transform** The real view (rotated) is in pink, the incorrect touchable area is in blue. <img src="https://user-images.githubusercontent.com/110431/41190136-a1a079a6-6bd9-11e8-906d-729015bcab6b.png" width="200"/> ## Changelog [Android] [Fixed] - Fix UIManager.measure() Pull Request resolved: https://github.com/facebook/react-native/pull/25836 Test Plan: Android now produces the same results as iOS as seen on these screenshots | Android without fix | Android with fix | iOS | | --- | --- | --- | | ![Screenshot_1564133103](https://user-images.githubusercontent.com/110431/61941632-28729b00-af98-11e9-9706-b13968b79df5.png) | ![Screenshot_1564130198](https://user-images.githubusercontent.com/110431/61941631-28729b00-af98-11e9-9ff3-5f2748077dbe.png) | ![Simulator Screen Shot - iPhone X - 2019-07-26 at 11 19 34](https://user-images.githubusercontent.com/110431/61941633-28729b00-af98-11e9-8dc4-22b61178242e.png) | Reviewed By: cpojer Differential Revision: D16598914 Pulled By: makovkastar fbshipit-source-id: d56b008b717ea17731fb09001cbd395aa1b044fe
This commit is contained in:
Родитель
2956eb266f
Коммит
28d50189f3
|
@ -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<SparseIntArray> 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 class NativeViewHierarchyManager {
|
|||
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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Загрузка…
Ссылка в новой задаче