Expose screen metrics and window metrics
Summary: public https://github.com/facebook/react-native/pull/4935 changed the window dimensions for android by replacing them with the actual screen dimensions. This changes the window dimensions back to their original values and adds `Dimensions.get('screen')` for the actual screen dimensions of the device. Reviewed By: astreet Differential Revision: D2921584 fb-gh-sync-id: 5d2677029c71d50691691dc651a11e9c8b115e8f shipit-source-id: 5d2677029c71d50691691dc651a11e9c8b115e8f
This commit is contained in:
parent
6f1417c849
commit
228a1fe7d4
|
@ -11,6 +11,7 @@
|
|||
*/
|
||||
'use strict';
|
||||
|
||||
var Platform = require('Platform');
|
||||
var UIManager = require('UIManager');
|
||||
|
||||
var invariant = require('invariant');
|
||||
|
@ -31,7 +32,21 @@ if (dimensions && dimensions.windowPhysicalPixels) {
|
|||
scale: windowPhysicalPixels.scale,
|
||||
fontScale: windowPhysicalPixels.fontScale,
|
||||
};
|
||||
if (Platform.OS === 'android') {
|
||||
// Screen and window dimensions are different on android
|
||||
var screenPhysicalPixels = dimensions.screenPhysicalPixels;
|
||||
dimensions.screen = {
|
||||
width: screenPhysicalPixels.width / screenPhysicalPixels.scale,
|
||||
height: screenPhysicalPixels.height / screenPhysicalPixels.scale,
|
||||
scale: screenPhysicalPixels.scale,
|
||||
fontScale: screenPhysicalPixels.fontScale,
|
||||
};
|
||||
|
||||
// delete so no callers rely on this existing
|
||||
delete dimensions.screenPhysicalPixels;
|
||||
} else {
|
||||
dimensions.screen = dimensions.window;
|
||||
}
|
||||
// delete so no callers rely on this existing
|
||||
delete dimensions.windowPhysicalPixels;
|
||||
}
|
||||
|
|
|
@ -308,8 +308,11 @@ import static com.facebook.react.bridge.ReactMarkerConstants.*;
|
|||
}
|
||||
|
||||
private static void setDisplayMetrics(Context context) {
|
||||
DisplayMetrics displayMetrics = new DisplayMetrics();
|
||||
displayMetrics.setTo(context.getResources().getDisplayMetrics());
|
||||
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
|
||||
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);
|
||||
|
||||
DisplayMetrics screenDisplayMetrics = new DisplayMetrics();
|
||||
screenDisplayMetrics.setTo(displayMetrics);
|
||||
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
Display display = wm.getDefaultDisplay();
|
||||
|
||||
|
@ -317,9 +320,8 @@ import static com.facebook.react.bridge.ReactMarkerConstants.*;
|
|||
// The real metrics include system decor elements (e.g. soft menu bar).
|
||||
//
|
||||
// See: http://developer.android.com/reference/android/view/Display.html#getRealMetrics(android.util.DisplayMetrics)
|
||||
if (Build.VERSION.SDK_INT >= 17){
|
||||
display.getRealMetrics(displayMetrics);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 17) {
|
||||
display.getRealMetrics(screenDisplayMetrics);
|
||||
} else {
|
||||
// For 14 <= API level <= 16, we need to invoke getRawHeight and getRawWidth to get the real dimensions.
|
||||
// Since react-native only supports API level 16+ we don't have to worry about other cases.
|
||||
|
@ -330,13 +332,13 @@ import static com.facebook.react.bridge.ReactMarkerConstants.*;
|
|||
try {
|
||||
Method mGetRawH = Display.class.getMethod("getRawHeight");
|
||||
Method mGetRawW = Display.class.getMethod("getRawWidth");
|
||||
displayMetrics.widthPixels = (Integer) mGetRawW.invoke(display);
|
||||
displayMetrics.heightPixels = (Integer) mGetRawH.invoke(display);
|
||||
screenDisplayMetrics.widthPixels = (Integer) mGetRawW.invoke(display);
|
||||
screenDisplayMetrics.heightPixels = (Integer) mGetRawH.invoke(display);
|
||||
} catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
|
||||
throw new RuntimeException("Error getting real dimensions for API level < 17", e);
|
||||
}
|
||||
}
|
||||
DisplayMetricsHolder.setDisplayMetrics(displayMetrics);
|
||||
DisplayMetricsHolder.setScreenDisplayMetrics(screenDisplayMetrics);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -410,7 +410,7 @@ public class ReactRootView extends SizeMonitoringFrameLayout implements RootView
|
|||
|
||||
getRootView().getWindowVisibleDisplayFrame(mVisibleViewArea);
|
||||
final int heightDiff =
|
||||
DisplayMetricsHolder.getDisplayMetrics().heightPixels - mVisibleViewArea.bottom;
|
||||
DisplayMetricsHolder.getWindowDisplayMetrics().heightPixels - mVisibleViewArea.bottom;
|
||||
if (mKeyboardHeight != heightDiff && heightDiff > mMinKeyboardHeightDetected) {
|
||||
// keyboard is now showing, or the keyboard height has changed
|
||||
mKeyboardHeight = heightDiff;
|
||||
|
|
|
@ -14,16 +14,39 @@ import android.util.DisplayMetrics;
|
|||
/**
|
||||
* Holds an instance of the current DisplayMetrics so we don't have to thread it through all the
|
||||
* classes that need it.
|
||||
* Note: windowDisplayMetrics are deprecated in favor of ScreenDisplayMetrics: window metrics
|
||||
* are supposed to return the drawable area but there's no guarantee that they correspond to the
|
||||
* actual size of the {@link ReactRootView}. Moreover, they are not consistent with what iOS
|
||||
* returns. Screen metrics returns the metrics of the entire screen, is consistent with iOS and
|
||||
* should be used instead.
|
||||
*/
|
||||
public class DisplayMetricsHolder {
|
||||
|
||||
private static DisplayMetrics sCurrentDisplayMetrics;
|
||||
private static DisplayMetrics sWindowDisplayMetrics;
|
||||
private static DisplayMetrics sScreenDisplayMetrics;
|
||||
|
||||
public static void setDisplayMetrics(DisplayMetrics displayMetrics) {
|
||||
sCurrentDisplayMetrics = displayMetrics;
|
||||
/**
|
||||
* @deprecated Use {@link #setScreenDisplayMetrics(DisplayMetrics)} instead. See comment above as
|
||||
* to why this is not correct to use.
|
||||
*/
|
||||
public static void setWindowDisplayMetrics(DisplayMetrics displayMetrics) {
|
||||
sWindowDisplayMetrics = displayMetrics;
|
||||
}
|
||||
|
||||
public static DisplayMetrics getDisplayMetrics() {
|
||||
return sCurrentDisplayMetrics;
|
||||
/**
|
||||
* @deprecated Use {@link #getScreenDisplayMetrics()} instead. See comment above as to why this
|
||||
* is not correct to use.
|
||||
*/
|
||||
@Deprecated
|
||||
public static DisplayMetrics getWindowDisplayMetrics() {
|
||||
return sWindowDisplayMetrics;
|
||||
}
|
||||
|
||||
public static void setScreenDisplayMetrics(DisplayMetrics screenDisplayMetrics) {
|
||||
sScreenDisplayMetrics = screenDisplayMetrics;
|
||||
}
|
||||
|
||||
public static DisplayMetrics getScreenDisplayMetrics() {
|
||||
return sScreenDisplayMetrics;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ public class PixelUtil {
|
|||
return TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_DIP,
|
||||
value,
|
||||
DisplayMetricsHolder.getDisplayMetrics());
|
||||
DisplayMetricsHolder.getWindowDisplayMetrics());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -40,7 +40,7 @@ public class PixelUtil {
|
|||
return TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_SP,
|
||||
value,
|
||||
DisplayMetricsHolder.getDisplayMetrics());
|
||||
DisplayMetricsHolder.getWindowDisplayMetrics());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -54,7 +54,7 @@ public class PixelUtil {
|
|||
* Convert from PX to DP
|
||||
*/
|
||||
public static float toDIPFromPixel(float value) {
|
||||
return value / DisplayMetricsHolder.getDisplayMetrics().density;
|
||||
return value / DisplayMetricsHolder.getWindowDisplayMetrics().density;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -91,7 +91,8 @@ import com.facebook.react.uimanager.events.TouchEventType;
|
|||
"ScaleAspectFill",
|
||||
ImageView.ScaleType.CENTER_CROP.ordinal())));
|
||||
|
||||
DisplayMetrics displayMetrics = DisplayMetricsHolder.getDisplayMetrics();
|
||||
DisplayMetrics displayMetrics = DisplayMetricsHolder.getWindowDisplayMetrics();
|
||||
DisplayMetrics screenDisplayMetrics = DisplayMetricsHolder.getScreenDisplayMetrics();
|
||||
constants.put(
|
||||
"Dimensions",
|
||||
MapBuilder.of(
|
||||
|
@ -106,7 +107,19 @@ import com.facebook.react.uimanager.events.TouchEventType;
|
|||
"fontScale",
|
||||
displayMetrics.scaledDensity,
|
||||
"densityDpi",
|
||||
displayMetrics.densityDpi)));
|
||||
displayMetrics.densityDpi),
|
||||
"screenPhysicalPixels",
|
||||
MapBuilder.of(
|
||||
"width",
|
||||
screenDisplayMetrics.widthPixels,
|
||||
"height",
|
||||
screenDisplayMetrics.heightPixels,
|
||||
"scale",
|
||||
screenDisplayMetrics.density,
|
||||
"fontScale",
|
||||
screenDisplayMetrics.scaledDensity,
|
||||
"densityDpi",
|
||||
screenDisplayMetrics.densityDpi)));
|
||||
|
||||
constants.put(
|
||||
"StyleConstants",
|
||||
|
|
|
@ -17,7 +17,6 @@ import android.graphics.Paint;
|
|||
|
||||
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.uimanager.ReactStylesDiffMap;
|
||||
import com.facebook.react.uimanager.DisplayMetricsHolder;
|
||||
import com.facebook.react.uimanager.annotations.ReactProp;
|
||||
import com.facebook.react.uimanager.ReactShadowNode;
|
||||
|
@ -39,7 +38,7 @@ public abstract class ARTVirtualNode extends ReactShadowNode {
|
|||
protected final float mScale;
|
||||
|
||||
public ARTVirtualNode() {
|
||||
mScale = DisplayMetricsHolder.getDisplayMetrics().density;
|
||||
mScale = DisplayMetricsHolder.getWindowDisplayMetrics().density;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -82,7 +82,7 @@ public class RootViewTest {
|
|||
mReactContext = new ReactApplicationContext(RuntimeEnvironment.application);
|
||||
mReactContext.initializeWithInstance(mCatalystInstanceMock);
|
||||
DisplayMetrics displayMetrics = mReactContext.getResources().getDisplayMetrics();
|
||||
DisplayMetricsHolder.setDisplayMetrics(displayMetrics);
|
||||
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);
|
||||
|
||||
UIManagerModule uiManagerModuleMock = mock(UIManagerModule.class);
|
||||
when(mCatalystInstanceMock.getNativeModule(UIManagerModule.class))
|
||||
|
|
|
@ -54,12 +54,14 @@ public class LayoutPropertyApplicatorTest {
|
|||
|
||||
@Before
|
||||
public void setup() {
|
||||
DisplayMetricsHolder.setDisplayMetrics(new DisplayMetrics());
|
||||
DisplayMetricsHolder.setWindowDisplayMetrics(new DisplayMetrics());
|
||||
DisplayMetricsHolder.setScreenDisplayMetrics(new DisplayMetrics());
|
||||
}
|
||||
|
||||
@After
|
||||
public void teardown() {
|
||||
DisplayMetricsHolder.setDisplayMetrics(null);
|
||||
DisplayMetricsHolder.setWindowDisplayMetrics(null);
|
||||
DisplayMetricsHolder.setScreenDisplayMetrics(null);
|
||||
}
|
||||
|
||||
public ReactStylesDiffMap buildStyles(Object... keysAndValues) {
|
||||
|
@ -309,7 +311,7 @@ public class LayoutPropertyApplicatorTest {
|
|||
public void testPropertiesResetToDefault() {
|
||||
DisplayMetrics displayMetrics = new DisplayMetrics();
|
||||
displayMetrics.density = 1.0f;
|
||||
DisplayMetricsHolder.setDisplayMetrics(displayMetrics);
|
||||
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);
|
||||
|
||||
LayoutShadowNode reactShadowNode = spy(new LayoutShadowNode());
|
||||
ReactStylesDiffMap map = buildStyles(
|
||||
|
|
|
@ -147,7 +147,8 @@ public class ReactPropConstantsTest {
|
|||
List<ViewManager> viewManagers = Arrays.<ViewManager>asList(new ViewManagerUnderTest());
|
||||
ReactApplicationContext reactContext = new ReactApplicationContext(RuntimeEnvironment.application);
|
||||
DisplayMetrics displayMetrics = reactContext.getResources().getDisplayMetrics();
|
||||
DisplayMetricsHolder.setDisplayMetrics(displayMetrics);
|
||||
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);
|
||||
DisplayMetricsHolder.setScreenDisplayMetrics(displayMetrics);
|
||||
UIManagerModule uiManagerModule = new UIManagerModule(
|
||||
reactContext,
|
||||
viewManagers,
|
||||
|
|
|
@ -60,7 +60,8 @@ public class UIManagerModuleConstantsTest {
|
|||
mUIImplementation = mock(UIImplementation.class);
|
||||
|
||||
DisplayMetrics displayMetrics = mReactContext.getResources().getDisplayMetrics();
|
||||
DisplayMetricsHolder.setDisplayMetrics(displayMetrics);
|
||||
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);
|
||||
DisplayMetricsHolder.setScreenDisplayMetrics(displayMetrics);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -109,7 +109,8 @@ public class UIManagerModuleTest {
|
|||
mReactContext.initializeWithInstance(mCatalystInstanceMock);
|
||||
|
||||
DisplayMetrics displayMetrics = mReactContext.getResources().getDisplayMetrics();
|
||||
DisplayMetricsHolder.setDisplayMetrics(displayMetrics);
|
||||
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);
|
||||
DisplayMetricsHolder.setScreenDisplayMetrics(displayMetrics);
|
||||
|
||||
UIManagerModule uiManagerModuleMock = mock(UIManagerModule.class);
|
||||
when(mCatalystInstanceMock.getNativeModule(UIManagerModule.class))
|
||||
|
|
|
@ -59,12 +59,12 @@ public class ReactImagePropertyTest {
|
|||
mContext.initializeWithInstance(mCatalystInstanceMock);
|
||||
mThemeContext = new ThemedReactContext(mContext, mContext);
|
||||
Fresco.initialize(mContext);
|
||||
DisplayMetricsHolder.setDisplayMetrics(new DisplayMetrics());
|
||||
DisplayMetricsHolder.setWindowDisplayMetrics(new DisplayMetrics());
|
||||
}
|
||||
|
||||
@After
|
||||
public void teardown() {
|
||||
DisplayMetricsHolder.setDisplayMetrics(null);
|
||||
DisplayMetricsHolder.setWindowDisplayMetrics(null);
|
||||
}
|
||||
|
||||
public ReactStylesDiffMap buildStyles(Object... keysAndValues) {
|
||||
|
|
|
@ -373,7 +373,8 @@ public class ReactTextTest {
|
|||
public UIManagerModule getUIManagerModule() {
|
||||
ReactApplicationContext reactContext = ReactTestHelper.createCatalystContextForTest();
|
||||
DisplayMetrics displayMetrics = reactContext.getResources().getDisplayMetrics();
|
||||
DisplayMetricsHolder.setDisplayMetrics(displayMetrics);
|
||||
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);
|
||||
DisplayMetricsHolder.setScreenDisplayMetrics(displayMetrics);
|
||||
List<ViewManager> viewManagers = Arrays.asList(
|
||||
new ViewManager[] {
|
||||
new ReactTextViewManager(),
|
||||
|
|
|
@ -60,7 +60,7 @@ public class ReactTextInputPropertyTest {
|
|||
mContext.initializeWithInstance(mCatalystInstanceMock);
|
||||
mThemedContext = new ThemedReactContext(mContext, mContext);
|
||||
mManager = new ReactTextInputManager();
|
||||
DisplayMetricsHolder.setDisplayMetrics(new DisplayMetrics());
|
||||
DisplayMetricsHolder.setWindowDisplayMetrics(new DisplayMetrics());
|
||||
}
|
||||
|
||||
public ReactStylesDiffMap buildStyles(Object... keysAndValues) {
|
||||
|
|
|
@ -183,7 +183,8 @@ public class TextInputTest {
|
|||
new ReactTextInputManager(),
|
||||
});
|
||||
DisplayMetrics displayMetrics = reactContext.getResources().getDisplayMetrics();
|
||||
DisplayMetricsHolder.setDisplayMetrics(displayMetrics);
|
||||
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);
|
||||
DisplayMetricsHolder.setScreenDisplayMetrics(displayMetrics);
|
||||
UIManagerModule uiManagerModule = new UIManagerModule(
|
||||
reactContext,
|
||||
viewManagers,
|
||||
|
|
Loading…
Reference in New Issue