From 8451585f3861776a1d8f67b8b0dfd1e9cc705ed6 Mon Sep 17 00:00:00 2001 From: Andrei Coman Date: Tue, 6 Sep 2016 08:34:02 -0700 Subject: [PATCH] Fix dimensions on orientation change Summary: This adds the `didUpdateDimensions` event that already exists on iOS, and updates the internal native dimensions data that needs repopulation after orientation change. Reviewed By: foghina Differential Revision: D3819364 fbshipit-source-id: fc2b3b4d1991d101e5de4439ccef2189bc65fd58 --- .../com/facebook/react/ReactRootView.java | 30 ++++++++++++++++++- .../react/uimanager/DisplayMetricsHolder.java | 16 ++++++---- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java b/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java index 3c8cde460..b2bea0d8e 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java @@ -11,11 +11,11 @@ package com.facebook.react; import javax.annotation.Nullable; -import android.app.Activity; import android.content.Context; import android.graphics.Rect; import android.os.Bundle; import android.util.AttributeSet; +import android.util.DisplayMetrics; import android.view.MotionEvent; import android.view.Surface; import android.view.View; @@ -346,6 +346,10 @@ public class ReactRootView extends SizeMonitoringFrameLayout implements RootView 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); } @@ -384,6 +388,30 @@ public class ReactRootView extends SizeMonitoringFrameLayout implements RootView sendEvent("namedOrientationDidChange", map); } + private void emitUpdateDimensionsEvent() { + DisplayMetrics windowDisplayMetrics = DisplayMetricsHolder.getWindowDisplayMetrics(); + DisplayMetrics screenDisplayMetrics = DisplayMetricsHolder.getScreenDisplayMetrics(); + + WritableMap windowDisplayMetricsMap = Arguments.createMap(); + windowDisplayMetricsMap.putInt("width", windowDisplayMetrics.widthPixels); + windowDisplayMetricsMap.putInt("height", windowDisplayMetrics.heightPixels); + windowDisplayMetricsMap.putDouble("scale", windowDisplayMetrics.density); + windowDisplayMetricsMap.putDouble("fontScale", windowDisplayMetrics.scaledDensity); + windowDisplayMetricsMap.putDouble("densityDpi", windowDisplayMetrics.densityDpi); + + WritableMap screenDisplayMetricsMap = Arguments.createMap(); + screenDisplayMetricsMap.putInt("width", screenDisplayMetrics.widthPixels); + screenDisplayMetricsMap.putInt("height", screenDisplayMetrics.heightPixels); + screenDisplayMetricsMap.putDouble("scale", screenDisplayMetrics.density); + screenDisplayMetricsMap.putDouble("fontScale", screenDisplayMetrics.scaledDensity); + screenDisplayMetricsMap.putDouble("densityDpi", screenDisplayMetrics.densityDpi); + + WritableMap dimensionsMap = Arguments.createMap(); + dimensionsMap.putMap("windowPhysicalPixels", windowDisplayMetricsMap); + dimensionsMap.putMap("screenPhysicalPixels", screenDisplayMetricsMap); + sendEvent("didUpdateDimensions", dimensionsMap); + } + private void sendEvent(String eventName, @Nullable WritableMap params) { if (mReactInstanceManager != null) { mReactInstanceManager.getCurrentReactContext() diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/DisplayMetricsHolder.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/DisplayMetricsHolder.java index 9c3e6baf5..04c26d8a2 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/DisplayMetricsHolder.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/DisplayMetricsHolder.java @@ -9,17 +9,17 @@ package com.facebook.react.uimanager; +import javax.annotation.Nullable; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + import android.content.Context; import android.os.Build; import android.util.DisplayMetrics; import android.view.Display; import android.view.WindowManager; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import javax.annotation.Nullable; - import com.facebook.infer.annotation.Assertions; /** @@ -43,11 +43,15 @@ public class DisplayMetricsHolder { public static void setWindowDisplayMetrics(DisplayMetrics displayMetrics) { sWindowDisplayMetrics = displayMetrics; } - + public static void initDisplayMetricsIfNotInitialized(Context context) { if (DisplayMetricsHolder.getScreenDisplayMetrics() != null) { return; } + initDisplayMetrics(context); + } + + public static void initDisplayMetrics(Context context) { DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);