Get the screen height in Android

2019-03-12 08:48发布

How can I get the available height of the screen in Android? I need to the height minus the status bar / menu bar or any other decorations that might be on screen and I need it to work for all devices. Also, I need to know this in the onCreate function. I know this question has been asked before but I have already tried their solutions and none of them work. Here are some of the things I have tried:

I have tested this code on API 7 - 17. Unfortunately, on API 13 there is extra space at bottom both horizontally and vertically and on API 10, 8, and 7 there is not enough space at the bottom both horizontally and vertically. (I have not tested on obsolete APIs):

Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
screenWidth = metrics.widthPixels;
screenHeight = metrics.heightPixels;

TypedValue tv = new TypedValue();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
{
    if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
        screenHeight -= TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
}

int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0)
    screenHeight -= getResources().getDimensionPixelSize(resourceId);

This does not take into account the status bar / menu bar:

Display display = getWindowManager().getDefaultDisplay();
screenWidth = display.getWidth();
screenHeight = display.getHeight();

Neither does this:

Point size = new Point();
getWindowManager().getDefaultDisplay().getSize(size);
screenWidth = size.x;
screenHeight = size.y;

Nor this:

Point size = new Point();
getWindowManager().getDefaultDisplay().getRealSize(size);
screenWidth = size.x;
screenHeight = size.y;

This does not work:

Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
// since SDK_INT = 1;
screenWidth = metrics.widthPixels;
screenHeight = metrics.heightPixels;
try
{
    // used when 17 > SDK_INT >= 14; includes window decorations (statusbar bar/menu bar)
    screenWidth = (Integer) Display.class.getMethod("getRawWidth").invoke(display);
    screenHeight = (Integer) Display.class.getMethod("getRawHeight").invoke(display);
}
catch (Exception ignored)
{
    // Do nothing
}
try
{
    // used when SDK_INT >= 17; includes window decorations (statusbar bar/menu bar)
    Point realSize = new Point();
    Display.class.getMethod("getRealSize", Point.class).invoke(display, realSize);
    screenWidth = realSize.x;
    screenHeight = realSize.y;
}
catch (Exception ignored)
{
    // Do nothing
}

I then used the following code to subtract the height of the status bar and menu bar from the screen height:

int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0)
    result = getResources().getDimensionPixelSize(resourceId);
screenHeight -= result;
result = 0;
if (screenHeight >= screenWidth)
    resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android");
else
    resourceId = getResources().getIdentifier("navigation_bar_height_landscape", "dimen", "android");
if (resourceId > 0)
    result = getResources().getDimensionPixelSize(resourceId);
screenHeight -= result;

On API 17 it correctly calculates the height of the status bar and menu bar in portrait but not in landscape. On API 10, it returns 0. I need it to work ideally on all devices or minimum API 7.

9条回答
一纸荒年 Trace。
2楼-- · 2019-03-12 09:22

Get the height of the root layout that is loaded by the activity. In case it does not fill the screen put it inside another layout with a height property of fill_parent.

查看更多
甜甜的少女心
3楼-- · 2019-03-12 09:24

How about setting up a subclassed View as the root of the Activity. Make this View fill the screen (it won't go past the status bar) and override onSizeChanged(). Store those values and write a getter for them.

查看更多
甜甜的少女心
4楼-- · 2019-03-12 09:31

I haven't tried different API's but I'm using these values to figure out whether or not the onscreen keyboard is up. Maybe you can try this and something comparable for width to get what you need?

Rect r = new Rect();
view.getWindowVisibleDisplayFrame(r);
int
    screenHeight = view.getRootView().getHeight(), // height of the entire screen
    appHeight = r.bottom - r.top, // height of the entire app
    statusBarHeight = r.top, // height of the statusbar
    pageHeight = view.getHeight(), // height of the app without title
    appTitleHeight = appHeight - pageHeight, // height of the only the app title
    topHeight = statusBarHeight + appTitleHeight;
查看更多
登录 后发表回答