diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java b/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java index 89a4fe55da7c28..fb7601750beada 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java @@ -16,6 +16,7 @@ import android.os.Build; import android.os.Bundle; import android.util.AttributeSet; +import android.util.DisplayMetrics; import android.view.MotionEvent; import android.view.Surface; import android.view.View; @@ -357,6 +358,8 @@ private class CustomGlobalLayoutListener implements ViewTreeObserver.OnGlobalLay private int mKeyboardHeight = 0; private int mDeviceRotation = 0; + private DisplayMetrics mWindowMetrics = new DisplayMetrics(); + private DisplayMetrics mScreenMetrics = new DisplayMetrics(); /* package */ CustomGlobalLayoutListener() { DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(getContext().getApplicationContext()); @@ -372,6 +375,7 @@ public void onGlobalLayout() { } checkForKeyboardEvents(); checkForDeviceOrientationChanges(); + checkForDeviceDimensionsChanges(); } private void checkForKeyboardEvents() { @@ -404,13 +408,37 @@ private void checkForDeviceOrientationChanges() { return; } mDeviceRotation = rotation; - // It's important to repopulate DisplayMetrics and export them before emitting the - // orientation change event, so that the Dimensions object returns the correct new values. - DisplayMetricsHolder.initDisplayMetrics(getContext()); - emitUpdateDimensionsEvent(); emitOrientationChanged(rotation); } + private void checkForDeviceDimensionsChanges() { + // Get current display metrics. + DisplayMetricsHolder.initDisplayMetrics(getContext()); + // Check changes to both window and screen display metrics since they may not update at the same time. + if (!areMetricsEqual(mWindowMetrics, DisplayMetricsHolder.getWindowDisplayMetrics()) || + !areMetricsEqual(mScreenMetrics, DisplayMetricsHolder.getScreenDisplayMetrics())) { + mWindowMetrics.setTo(DisplayMetricsHolder.getWindowDisplayMetrics()); + mScreenMetrics.setTo(DisplayMetricsHolder.getScreenDisplayMetrics()); + emitUpdateDimensionsEvent(); + } + } + + private boolean areMetricsEqual(DisplayMetrics displayMetrics, DisplayMetrics otherMetrics) { + if (Build.VERSION.SDK_INT >= 17) { + return displayMetrics.equals(otherMetrics); + } else { + // DisplayMetrics didn't have an equals method before API 17. + // Check all public fields manually. + return displayMetrics.widthPixels == otherMetrics.widthPixels && + displayMetrics.heightPixels == otherMetrics.heightPixels && + displayMetrics.density == otherMetrics.density && + displayMetrics.densityDpi == otherMetrics.densityDpi && + displayMetrics.scaledDensity == otherMetrics.scaledDensity && + displayMetrics.xdpi == otherMetrics.xdpi && + displayMetrics.ydpi == otherMetrics.ydpi; + } + } + private void emitOrientationChanged(final int newRotation) { String name; double rotationDegrees;