mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Take viewport offset into account in UIManager.measureInWindow
Summary: D23021903 (https://github.com/facebook/react-native/commit/154ce789723f6e65785bcfc00da399ad9184bdfb) but for Android. Changelog: [Internal] Reviewed By: sammy-SC Differential Revision: D23640968 fbshipit-source-id: 7a743ebd0ea2b573d6ef17b418ad98ec616b11d3
This commit is contained in:
committed by
Facebook GitHub Bot
parent
a315e4cd30
commit
78b42d7fb7
@@ -14,6 +14,7 @@ import static com.facebook.systrace.Systrace.TRACE_TAG_REACT_JAVA_BRIDGE;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.util.AttributeSet;
|
||||
@@ -291,7 +292,12 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
// No-op since UIManagerModule handles actually laying out children.
|
||||
// No-op in non-Fabric since UIManagerModule handles actually laying out children.
|
||||
|
||||
// In Fabric, update LayoutSpecs just so we update the offsetX and offsetY.
|
||||
if (mWasMeasured && getUIManagerType() == FABRIC) {
|
||||
updateRootLayoutSpecs(mWidthMeasureSpec, mHeightMeasureSpec);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -405,6 +411,20 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
|
||||
return appProperties != null ? appProperties.getString("surfaceID") : null;
|
||||
}
|
||||
|
||||
public static Point getViewportOffset(View v) {
|
||||
int[] locationInWindow = new int[2];
|
||||
v.getLocationInWindow(locationInWindow);
|
||||
|
||||
// we need to subtract visibleWindowCoords - to subtract possible window insets, split
|
||||
// screen or multi window
|
||||
Rect visibleWindowFrame = new Rect();
|
||||
v.getWindowVisibleDisplayFrame(visibleWindowFrame);
|
||||
locationInWindow[0] -= visibleWindowFrame.left;
|
||||
locationInWindow[1] -= visibleWindowFrame.top;
|
||||
|
||||
return new Point(locationInWindow[0], locationInWindow[1]);
|
||||
}
|
||||
|
||||
private void updateRootLayoutSpecs(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
if (mReactInstanceManager == null) {
|
||||
FLog.w(TAG, "Unable to update root layout specs for uninitialized ReactInstanceManager");
|
||||
@@ -418,7 +438,17 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
|
||||
UIManagerHelper.getUIManager(reactApplicationContext, getUIManagerType());
|
||||
// Ignore calling updateRootLayoutSpecs if UIManager is not properly initialized.
|
||||
if (uiManager != null) {
|
||||
uiManager.updateRootLayoutSpecs(getRootViewTag(), widthMeasureSpec, heightMeasureSpec);
|
||||
// In Fabric only, get position of view within screen
|
||||
int offsetX = 0;
|
||||
int offsetY = 0;
|
||||
if (getUIManagerType() == FABRIC) {
|
||||
Point viewportOffset = getViewportOffset(this);
|
||||
offsetX = viewportOffset.x;
|
||||
offsetY = viewportOffset.y;
|
||||
}
|
||||
|
||||
uiManager.updateRootLayoutSpecs(
|
||||
getRootViewTag(), widthMeasureSpec, heightMeasureSpec, offsetX, offsetY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,11 +41,12 @@ public interface UIManager extends JSIModule, PerformanceCounter {
|
||||
|
||||
/**
|
||||
* Updates the layout specs of the RootShadowNode based on the Measure specs received by
|
||||
* parameters.
|
||||
* parameters. offsetX and offsetY are the position of the RootView within the screen.
|
||||
*/
|
||||
@UiThread
|
||||
@ThreadConfined(UI)
|
||||
void updateRootLayoutSpecs(int rootTag, int widthMeasureSpec, int heightMeasureSpec);
|
||||
void updateRootLayoutSpecs(
|
||||
int rootTag, int widthMeasureSpec, int heightMeasureSpec, int offsetX, int offsetY);
|
||||
|
||||
/**
|
||||
* Dispatches the commandId received by parameter to the view associated with the reactTag. The
|
||||
|
||||
@@ -52,6 +52,8 @@ public class Binding {
|
||||
float maxWidth,
|
||||
float minHeight,
|
||||
float maxHeight,
|
||||
float offsetX,
|
||||
float offsetY,
|
||||
boolean isRTL,
|
||||
boolean doLeftAndRightSwapInRTL);
|
||||
|
||||
@@ -67,6 +69,8 @@ public class Binding {
|
||||
float maxWidth,
|
||||
float minHeight,
|
||||
float maxHeight,
|
||||
float offsetX,
|
||||
float offsetY,
|
||||
boolean isRTL,
|
||||
boolean doLeftAndRightSwapInRTL);
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import static com.facebook.react.uimanager.common.UIManagerType.FABRIC;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Point;
|
||||
import android.os.SystemClock;
|
||||
import android.view.View;
|
||||
import androidx.annotation.AnyThread;
|
||||
@@ -34,6 +35,7 @@ import com.facebook.debug.holder.PrinterHolder;
|
||||
import com.facebook.debug.tags.ReactDebugOverlayTags;
|
||||
import com.facebook.infer.annotation.ThreadConfined;
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
import com.facebook.react.ReactRootView;
|
||||
import com.facebook.react.bridge.LifecycleEventListener;
|
||||
import com.facebook.react.bridge.NativeMap;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
@@ -230,6 +232,9 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||
}
|
||||
mMountingManager.addRootView(rootTag, rootView);
|
||||
mReactContextForRootTag.put(rootTag, reactContext);
|
||||
|
||||
Point viewportOffset = ReactRootView.getViewportOffset(rootView);
|
||||
|
||||
mBinding.startSurfaceWithConstraints(
|
||||
rootTag,
|
||||
moduleName,
|
||||
@@ -238,6 +243,8 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||
getMaxSize(widthMeasureSpec),
|
||||
getMinSize(heightMeasureSpec),
|
||||
getMaxSize(heightMeasureSpec),
|
||||
viewportOffset.x,
|
||||
viewportOffset.y,
|
||||
I18nUtil.getInstance().isRTL(context),
|
||||
I18nUtil.getInstance().doLeftAndRightSwapInRTL(context));
|
||||
return rootTag;
|
||||
@@ -957,7 +964,11 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||
@UiThread
|
||||
@ThreadConfined(UI)
|
||||
public void updateRootLayoutSpecs(
|
||||
final int rootTag, final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
final int rootTag,
|
||||
final int widthMeasureSpec,
|
||||
final int heightMeasureSpec,
|
||||
final int offsetX,
|
||||
final int offsetY) {
|
||||
|
||||
if (ENABLE_FABRIC_LOGS) {
|
||||
FLog.d(TAG, "Updating Root Layout Specs");
|
||||
@@ -977,6 +988,8 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||
getMaxSize(widthMeasureSpec),
|
||||
getMinSize(heightMeasureSpec),
|
||||
getMaxSize(heightMeasureSpec),
|
||||
offsetX,
|
||||
offsetY,
|
||||
isRTL,
|
||||
doLeftAndRightSwapInRTL);
|
||||
}
|
||||
|
||||
@@ -101,6 +101,8 @@ void Binding::startSurfaceWithConstraints(
|
||||
jfloat maxWidth,
|
||||
jfloat minHeight,
|
||||
jfloat maxHeight,
|
||||
jfloat offsetX,
|
||||
jfloat offsetY,
|
||||
jboolean isRTL,
|
||||
jboolean doLeftAndRightSwapInRTL) {
|
||||
SystraceSection s("FabricUIManagerBinding::startSurfaceWithConstraints");
|
||||
@@ -123,6 +125,8 @@ void Binding::startSurfaceWithConstraints(
|
||||
Size{maxWidth / pointScaleFactor_, maxHeight / pointScaleFactor_};
|
||||
|
||||
LayoutContext context;
|
||||
context.viewportOffset =
|
||||
Point{offsetX / pointScaleFactor_, offsetY / pointScaleFactor_};
|
||||
context.pointScaleFactor = {pointScaleFactor_};
|
||||
context.swapLeftAndRightInRTL = doLeftAndRightSwapInRTL;
|
||||
LayoutConstraints constraints = {};
|
||||
@@ -178,6 +182,8 @@ void Binding::setConstraints(
|
||||
jfloat maxWidth,
|
||||
jfloat minHeight,
|
||||
jfloat maxHeight,
|
||||
jfloat offsetX,
|
||||
jfloat offsetY,
|
||||
jboolean isRTL,
|
||||
jboolean doLeftAndRightSwapInRTL) {
|
||||
SystraceSection s("FabricUIManagerBinding::setConstraints");
|
||||
@@ -194,6 +200,8 @@ void Binding::setConstraints(
|
||||
Size{maxWidth / pointScaleFactor_, maxHeight / pointScaleFactor_};
|
||||
|
||||
LayoutContext context;
|
||||
context.viewportOffset =
|
||||
Point{offsetX / pointScaleFactor_, offsetY / pointScaleFactor_};
|
||||
context.pointScaleFactor = {pointScaleFactor_};
|
||||
context.swapLeftAndRightInRTL = doLeftAndRightSwapInRTL;
|
||||
LayoutConstraints constraints = {};
|
||||
|
||||
@@ -48,6 +48,8 @@ class Binding : public jni::HybridClass<Binding>,
|
||||
jfloat maxWidth,
|
||||
jfloat minHeight,
|
||||
jfloat maxHeight,
|
||||
jfloat offsetX,
|
||||
jfloat offsetY,
|
||||
jboolean isRTL,
|
||||
jboolean doLeftAndRightSwapInRTL);
|
||||
|
||||
@@ -74,6 +76,8 @@ class Binding : public jni::HybridClass<Binding>,
|
||||
jfloat maxWidth,
|
||||
jfloat minHeight,
|
||||
jfloat maxHeight,
|
||||
jfloat offsetX,
|
||||
jfloat offsetY,
|
||||
jboolean isRTL,
|
||||
jboolean doLeftAndRightSwapInRTL);
|
||||
|
||||
|
||||
@@ -926,10 +926,14 @@ public class UIManagerModule extends ReactContextBaseJavaModule
|
||||
|
||||
/**
|
||||
* Updates the styles of the {@link ReactShadowNode} based on the Measure specs received by
|
||||
* parameters.
|
||||
* parameters. offsetX and offsetY aren't used in non-Fabric, so they're ignored here.
|
||||
*/
|
||||
public void updateRootLayoutSpecs(
|
||||
final int rootViewTag, final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
final int rootViewTag,
|
||||
final int widthMeasureSpec,
|
||||
final int heightMeasureSpec,
|
||||
int offsetX,
|
||||
int offsetY) {
|
||||
ReactApplicationContext reactApplicationContext = getReactApplicationContext();
|
||||
reactApplicationContext.runOnNativeModulesQueueThread(
|
||||
new GuardedRunnable(reactApplicationContext) {
|
||||
|
||||
Reference in New Issue
Block a user