Use `getRealMetrics` for display metrics. Closes #4934
Summary: Fixes https://github.com/facebook/react-native/issues/4934. Since API level 17, there has a `Display.getRealMetrics` method. This allows us to get the actual sizes of the screen (including soft menu bar and other system decor elements). See: http://developer.android.com/reference/android/view/Display.html#getRealMetrics(android.util.DisplayMetrics) I'm not sure if there is a good way to write unit or integration tests for this. Please let me know if there are any suggestions or concerns. Closes https://github.com/facebook/react-native/pull/4935 Reviewed By: svcscm Differential Revision: D2811091 Pulled By: bestander fb-gh-sync-id: fed4e357db7eb36d638eebabd8ced4bdffd766a4
This commit is contained in:
parent
bb5a6be9dd
commit
8e603940e3
|
@ -11,11 +11,17 @@ package com.facebook.react.uimanager;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Build;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
|
import android.view.Display;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
|
||||||
import com.facebook.csslayout.CSSLayoutContext;
|
import com.facebook.csslayout.CSSLayoutContext;
|
||||||
import com.facebook.infer.annotation.Assertions;
|
import com.facebook.infer.annotation.Assertions;
|
||||||
|
@ -84,7 +90,9 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
|
||||||
UIImplementation uiImplementation) {
|
UIImplementation uiImplementation) {
|
||||||
super(reactContext);
|
super(reactContext);
|
||||||
mEventDispatcher = new EventDispatcher(reactContext);
|
mEventDispatcher = new EventDispatcher(reactContext);
|
||||||
DisplayMetrics displayMetrics = reactContext.getResources().getDisplayMetrics();
|
|
||||||
|
DisplayMetrics displayMetrics = getDisplayMetrics();
|
||||||
|
|
||||||
DisplayMetricsHolder.setDisplayMetrics(displayMetrics);
|
DisplayMetricsHolder.setDisplayMetrics(displayMetrics);
|
||||||
mModuleConstants = createConstants(displayMetrics, viewManagerList);
|
mModuleConstants = createConstants(displayMetrics, viewManagerList);
|
||||||
mUIImplementation = uiImplementation;
|
mUIImplementation = uiImplementation;
|
||||||
|
@ -452,4 +460,39 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
|
||||||
public void sendAccessibilityEvent(int tag, int eventType) {
|
public void sendAccessibilityEvent(int tag, int eventType) {
|
||||||
mUIImplementation.sendAccessibilityEvent(tag, eventType);
|
mUIImplementation.sendAccessibilityEvent(tag, eventType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private DisplayMetrics getDisplayMetrics() {
|
||||||
|
Context context = getReactApplicationContext();
|
||||||
|
|
||||||
|
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
|
||||||
|
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||||
|
Display display = wm.getDefaultDisplay();
|
||||||
|
|
||||||
|
// Get the real display metrics if we are using API level 17 or higher.
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
} 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.
|
||||||
|
//
|
||||||
|
// Reflection exceptions are rethrown at runtime.
|
||||||
|
//
|
||||||
|
// See: http://stackoverflow.com/questions/14341041/how-to-get-real-screen-height-and-width/23861333#23861333
|
||||||
|
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);
|
||||||
|
} catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
|
||||||
|
throw new RuntimeException("Error getting real dimensions for API level < 17", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return displayMetrics;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue