Skip to content

Commit

Permalink
Use getRealMetrics for display metrics. Closes #4934
Browse files Browse the repository at this point in the history
Summary:
Fixes #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 #4935

Reviewed By: svcscm

Differential Revision: D2811091

Pulled By: bestander

fb-gh-sync-id: fed4e357db7eb36d638eebabd8ced4bdffd766a4
  • Loading branch information
jaysoo authored and facebook-github-bot-7 committed Feb 1, 2016
1 parent bb5a6be commit 8e60394
Showing 1 changed file with 44 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,17 @@

import javax.annotation.Nullable;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import android.content.Context;
import android.os.Build;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.WindowManager;

import com.facebook.csslayout.CSSLayoutContext;
import com.facebook.infer.annotation.Assertions;
Expand Down Expand Up @@ -84,7 +90,9 @@ public UIManagerModule(
UIImplementation uiImplementation) {
super(reactContext);
mEventDispatcher = new EventDispatcher(reactContext);
DisplayMetrics displayMetrics = reactContext.getResources().getDisplayMetrics();

DisplayMetrics displayMetrics = getDisplayMetrics();

DisplayMetricsHolder.setDisplayMetrics(displayMetrics);
mModuleConstants = createConstants(displayMetrics, viewManagerList);
mUIImplementation = uiImplementation;
Expand Down Expand Up @@ -452,4 +460,39 @@ public EventDispatcher getEventDispatcher() {
public void sendAccessibilityEvent(int tag, int 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;
}

}

5 comments on commit 8e60394

@Larney11
Copy link

@Larney11 Larney11 commented on 8e60394 Jul 26, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jaysoo But how can this file be implemented into my React-Native Android project?

I have had this problem for a long time. I created an issue on you react-native-extra-dimensions-android repository if you have the time could you please have a look.
Thanks.

@code-by
Copy link

@code-by code-by commented on 8e60394 Mar 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any example?

@Larney11
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@code-by
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Larney11 but what this PR fixes in RN? Do I still need https://github.com/BelinChung/react-native-extra-dimensions-android to detect real screen size (exclude status bar, menu bar, etc)?

@Larney11
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taken from https://github.com/BelinChung/react-native-extra-dimensions-android

There is currently a bug in React Native where Dimensions.get('window').height sometimes returns the wrong value.

follow this link for more details.

I think you will still need to use what I explained on StackOverflow.

Please sign in to comment.