java 在Android中获取屏幕高度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17353822/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-01 01:46:25  来源:igfitidea点击:

Get the screen height in Android

javaandroidandroid-layoutlayoutscreen

提问by Dan Bray

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:

如何在 Android 中获取屏幕的可用高度?我需要高度减去状态栏/菜单栏或屏幕上可能出现的任何其他装饰,我需要它适用于所有设备。另外,我需要在 onCreate 函数中知道这一点。我知道之前有人问过这个问题,但我已经尝试过他们的解决方案,但都没有奏效。以下是我尝试过的一些方法:

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):

我已经在 API 7 - 17 上测试了这段代码。不幸的是,在 API 13 上,底部水平和垂直方向都有额外的空间,而 API 10、8 和 7 底部的水平和垂直方向都没有足够的空间。(我还没有对过时的 API 进行测试):

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.

在 API 17 上,它可以正确计算纵向状态栏和菜单栏的高度,但不能正确计算横向状态栏的高度。在 API 10 上,它返回 0。我需要它在所有设备或最低 API 7 上都能理想地工作。

采纳答案by Karthik Balakrishnan

Working solution:

工作解决方案:

Create two dummy views :

创建两个虚拟视图:

 <View
    android:id="@+id/top"
    android:layout_height="0dp"
    android:layout_width="match_parent"
    android:layout_alignParentTop="true" />

<View
        android:id="@+id/bottom"
        android:layout_height="0dp"
        android:layout_width="match_parent"
        android:layout_alignParentBottom="true" />

Now, you should call getLocationOnScreen(int [])on these two views to receive their locations. This function returns an array of 2 integers. The first being x and the second y. We require only y. Also note that correct values are returned only AFTER all the views are created and the onCreatemethod is exited.

现在,您应该调用getLocationOnScreen(int [])这两个视图来接收它们的位置。此函数返回一个包含 2 个整数的数组。第一个是 x,第二个是 y。我们只需要 y。另请注意,只有在创建所有视图并onCreate退出该方法后,才会返回正确的值。

I tested this code on a regular fragment called from a viewpager.

我在从 viewpager 调用的常规片段上测试了这段代码。

The code was in the onCreateViewmethod of my fragment. I still had to use a postDelayedto get the correct values.

代码在onCreateView我的片段的方法中。我仍然必须使用 apostDelayed来获得正确的值。

final View top = (View) view.findViewById(R.id.top);
    final View bottom = (View) view.findViewById(R.id.bottom);
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {

            int topLoc[] = new int[2];
            top.getLocationOnScreen(topLoc);
            int BottomLoc[] = new int[2];
            bottom.getLocationOnScreen(BottomLoc);
            Log.d(Constants.debug, "topY: "+ topLoc[1]+" BottomY:" + BottomLoc[1]);
        }
    },4000);

I have a Nexus 4.

我有一个 Nexus 4。

In regular mode (status bar and the soft buttons shown) :

在常规模式下(显示状态栏和软按钮):

07-05 02:28:23.367      565-565/com.torcellite.xx D/xx: topY: 50 BottomY:1182

In full screen mode (no status bar or soft buttons shown) :

在全屏模式下(没有显示状态栏或软按钮):

07-05 02:29:17.360      707-707/com.torcellite.xx D/xx: topY: 0 BottomY:1280

All you have to do now is subtract.

你现在要做的就是减法。

回答by Ponmalar

If you want the the display dimensions in pixels you can use getSize:

如果您想要以像素为单位的显示尺寸,您可以使用getSize

Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;

If you're not in an Activityyou can get the default Display via WINDOW_SERVICE:

如果您不在,则Activity可以通过WINDOW_SERVICE以下方式获得默认显示:

WindowManager wm = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
display.getSize(size);
int width = size.x;
int height = size.y;

Before getSizewas introduced (in API level 13), you could use the getWidth and getHeight methods that are now deprecated:

getSize引入之前(在 API 级别 13 中),您可以使用现在已弃用getWidth 和 getHeight 方法:

Display display = getWindowManager().getDefaultDisplay(); 
int width = display.getWidth();  // deprecated
int height = display.getHeight();  // deprecated

Referred from :Get screen dimensions in pixels

引用自:以像素为单位获取屏幕尺寸

回答by Carnal

final View view = findViewById(R.id.root);
ViewTreeObserver vto = view.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        // calculate the height in here...

        ViewTreeObserver vto = view.getViewTreeObserver();
        vto.removeGlobalOnLayoutListener(this);
    }
});

Use this listener inside onCreate(available since api 1). You will need to assign the id @+id/rootto the parent in your xml layout. There is no way the size can return a result of 0, since this listener makes a callback whenever the layouts has been positioned in view.

在内部使用此侦听器onCreate(自 api 1 起可用)。您需要将 id 分配给@+id/rootxml 布局中的父级。大小无法返回 0 结果,因为只要布局已定位在视图中,此侦听器就会进行回调。

回答by Parag Chauhan

For Display

展示用

DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int width = displaymetrics.widthPixels;

For Status Bar

对于状态栏

public int getStatusBarHeight() {
        int result = 0;
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }

回答by Gelunox

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?

我没有尝试过不同的 API,但我正在使用这些值来确定屏幕键盘是否已启动。也许你可以试试这个和宽度相当的东西来得到你需要的东西?

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;

回答by Vaishali Sharma

Display currentDisplay = getWindowManager().getDefaultDisplay();
        float dw = currentDisplay.getWidth();
        float dh = currentDisplay.getHeight();

dhwill give you the screen height.

dh会给你屏幕高度。

回答by Ryan

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.

如何将子类视图设置为活动的根。使这个 View 填满屏幕(它不会越过状态栏)并覆盖onSizeChanged()。存储这些值并为它们编写一个 getter。

回答by pulkit gupta

It may not answer your question, but it could be useful to know (I was looking for it myself when I came to this question) that if you need a View's dimension but your code is being executed when its layout has not been laid out yet (for example in onCreate() ) you can setup a ViewTreeObserver.OnGlobalLayoutListener with View.getViewTreeObserver().addOnGlobalLayoutListener() and put the relevant code that needs the view's dimension there. The listener's callback will be called when the layout will have been laid out.

它可能无法回答您的问题,但如果您需要一个视图的维度,但您的代码在其布局尚未布局时正在执行,那么知道(我在遇到这个问题时自己正在寻找它)可能会很有用(例如在 onCreate() 中)您可以使用 View.getViewTreeObserver().addOnGlobalLayoutListener() 设置一个 ViewTreeObserver.OnGlobalLayoutListener 并将需要视图维度的相关代码放在那里。当布局已经布置好时,将调用侦听器的回调。

courtesy-Francesco Feltrinelli

礼貌-弗朗西斯科·费尔特里内利

You could try to do this.

你可以尝试这样做。

回答by SceLus

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.

获取活动加载的根布局的高度。如果它没有填满屏幕,请将其放入另一个具有 fill_parent 高度属性的布局中。