Java 如何在Android中获得屏幕高度?

Java 如何在Android中获得屏幕高度?,java,android,size,height,screen,Java,Android,Size,Height,Screen,如何在Android中获得可用的屏幕高度?我需要的高度减去状态栏/菜单栏或任何其他装饰,可能会在屏幕上,我需要它的所有设备的工作。另外,我需要在onCreate函数中了解这一点。我知道以前有人问过这个问题,但我已经尝试过他们的解决方案,但没有一个有效。以下是我尝试过的一些事情: 这不考虑状态栏/菜单栏: Display display = getWindowManager().getDefaultDisplay(); screenWidth = display.getWidth(); scree

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

这不考虑状态栏/菜单栏:

Display display = getWindowManager().getDefaultDisplay();
screenWidth = display.getWidth();
screenHeight = display.getHeight();
这也不是:

Point size = new Point();
getWindowManager().getDefaultDisplay().getSize(size);
screenWidth = size.x;
screenHeight = size.y;
这也不是:

Point size = new Point();
getWindowManager().getDefaultDisplay().getRealSize(size);
screenWidth = size.x;
screenHeight = size.y;
这不起作用:

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
}
然后,我使用以下代码从屏幕高度中减去状态栏和菜单栏的高度:

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;

在API 17上,它给出了正确计算纵向(而非横向)状态栏和菜单栏高度的公式。在API 10上,它返回0。我需要它在所有设备或最低API 10的理想工作

我想出的最佳解决方案是:

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

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

您是否尝试过在活动类的onWindowFocusChanged中进行高度计算?通过计算您真正想要的内容,而不是弄乱菜单栏等,这消除了API的麻烦

@Override
public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        View content = getWindow().findViewById(Window.ID_ANDROID_CONTENT);
        screenHeight=content.getHeight();
}

以下是我如何为所有设备获得正确的屏幕尺寸:

public class MainActivity extends Activity
{
    static int ScreenWidth;
    static int ScreenHeight;
    static int ScreenWidthLandscape;
    static int ScreenHeightLandscape;

    private RelativeLayout layout;
    private RelativeLayout.LayoutParams params;
    private View top;
    private View bottom;

    @SuppressWarnings("deprecation")
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        layout = new RelativeLayout(this);
        top = new View(this);
        bottom = new View(this);
        RelativeLayout.LayoutParams viewParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1);
        viewParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
        top.setLayoutParams(viewParams);
        viewParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1);
        viewParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
        bottom.setLayoutParams(viewParams);
        layout.addView(top);
        layout.addView(bottom);
        setContentView(layout);
        final Intent intent = new Intent(this, myPackage.learnSpanishVerbs.Start.class);

        final View view = getWindow().getDecorView().getRootView();
        ViewTreeObserver vto = view.getViewTreeObserver();
        vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener()
        {
            @Override
            public void onGlobalLayout()
            {
                int topLoc[] = new int[2];
                top.getLocationOnScreen(topLoc);
                int BottomLoc[] = new int[2];
                bottom.getLocationOnScreen(BottomLoc);
                boolean portrait = getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE;
                if (portrait)
                {
                    ScreenWidth = top.getWidth();
                    ScreenHeight = BottomLoc[1] - topLoc[1];
                }
                else
                {
                    ScreenWidthLandscape = top.getWidth();
                    ScreenHeightLandscape = BottomLoc[1] - topLoc[1];
                }

                if (Build.VERSION.SDK_INT < 16)
                    view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                else
                    view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                startActivity(intent);
                finish();
            } 
        });
    }
}
公共类MainActivity扩展活动
{
静态屏幕宽度;
静态屏幕高度;
静态景观;
静态屏幕高度景观;
私人住宅布局;
私有RelativeLayout.LayoutParams参数;
私家视窗;
私有视图底部;
@抑制警告(“弃用”)
@TargetApi(Build.VERSION\u code.JELLY\u BEAN)
@凌驾
创建时受保护的void(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
布局=新的RelativeLayout(本);
顶部=新视图(此视图);
底部=新视图(此);
RelativeLayout.LayoutParams viewParams=新的RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_父项,1);
viewParams.addRule(RelativeLayout.ALIGN\u PARENT\u TOP);
top.setLayoutParams(viewParams);
viewParams=新的RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_父项,1);
viewParams.addRule(RelativeLayout.ALIGN\u PARENT\u BOTTOM);
bottom.setLayoutParams(viewParams);
布局。添加视图(顶部);
布局。添加视图(底部);
setContentView(布局);
最终意图=新意图(这个,myPackage.learnPanishVerbs.Start.class);
最终视图=getWindow().getDecorView().getRootView();
ViewTreeObserver vto=view.getViewTreeObserver();
vto.addOnGlobalLayoutListener(新的OnGlobalLayoutListener()
{
@凌驾
公共图书馆
{
int-topLoc[]=新的int[2];
top.GetLocationOn屏幕(topLoc);
int BottomLoc[]=新int[2];
底部。getLocationOnScreen(底部定位);
布尔纵向=getResources().getConfiguration().orientation!=Configuration.orientation\u横向;
如果(肖像)
{
ScreenWidth=top.getWidth();
屏幕高度=底部位置[1]-顶部位置[1];
}
其他的
{
ScreenWidth横向=top.getWidth();
屏幕高度横向=底部位置[1]-顶部位置[1];
}
如果(Build.VERSION.SDK_INT<16)
view.getViewTreeObserver();
其他的
view.getViewTreeObserver();
星触觉(意向);
完成();
} 
});
}
}

你试过这个代码吗:是的,我试过了。见下面我的答案。感谢可能的副本我没有尝试过这个,但只有在
OnCreate
之前调用它,它才会起作用。只是为了我自己的教育,您使用哪些方法或命令需要在OnCreate之前完成?在我自己的解决方案中,我能够将许多功能从onCreate移动到onWindosFocusChange,并且在为用户显示屏幕数据后,屏幕显示正确。我只需要在onCreate之前或期间获得正确的屏幕高度和宽度,以便为我的对象提供正确的大小和位置。我让它工作。看看我的解决方案。此外,您的代码将无法工作,因为首先调用OnCreate。无论如何谢谢你的帮助我很高兴你有你需要的!谢谢你和我一起工作!你真的需要那些顶视图和底视图吗?在整个屏幕上有一个布局,并在
onGlobalLayout
中获得其高度,这还不够吗?您能找到解决方案吗?