6

如何在 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 上理想地工作。

4

3 回答 3

0

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

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 上进行测试)。

于 2013-06-27T02:03:48.813 回答
0

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

@Override
public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        View content = getWindow().findViewById(Window.ID_ANDROID_CONTENT);
        screenHeight=content.getHeight();
}
于 2013-07-10T17:36:05.640 回答
0

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

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();
            } 
        });
    }
}
于 2013-07-10T18:55:42.140 回答