不显示状态栏的显示指标?

35

我需要获取应用程序在设备上可以使用的显示矩形的尺寸。为此,我尝试使用以下代码:

Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
我的问题是,它给了我整个显示屏的高度,而显示器顶部有一个“状态/通知”栏,应用程序无法使用它。我需要应用程序可以使用的实际尺寸。为了帮助您更好地理解问题,我将留下一张图片: enter image description here
2个回答

40

解决这一问题的最大难点在于,在布局完成之前,通常无法获得视图大小的真实值。这意味着在onCreate()方法(通常也包括onResume()方法)中进行计算是过早的。以下代码将获取表示Activity内容视图的视图,此时您可以检查其高度和宽度:

View content = getWindow().findViewById(Window.ID_ANDROID_CONTENT);
Log.d("DISPLAY", content.getWidth() + " x " + content.getHeight());

如果您在Activity中设置了任何标题视图,这也会被考虑在内。如果该布局在两个维度上都设置为fill_parent,则您还可以获取对设置为内容视图的根布局的引用并执行相同的操作。

我经常在onWindowFocusChanged()方法中进行此类调用,该方法将在您的Activity即将显示给用户时调用。

希望能有所帮助!


如果这个有效,你不仅解决了我的问题,而且还大大减少了我的代码量。我曾经遇到过很多视图使用fillParent和MatchParent时无法返回其尺寸的问题。 - J-Rou
这给了我整个显示度量(与之前获得的相同值),但它允许我获取一个具有MATCH_PARENT、MATCH_PARENT的画廊的大小,其父级是屏幕的可用部分,因此我能够获得我想要的。非常感谢,我一直在尝试解决这个问题很长时间了。 - J-Rou
1
onWindowFocusChanged()中进行调用是个不错的技巧。我曾经很绝望地想找到一种方法,在启动时允许测量视图。 - Sébastien
你也可以尝试使用onAttachedToWindow(),或者将布局的根视图制作为一个自定义子类的布局,以便您可以监视onMeasure()onSizeChanged() - devunwired
如果您打开键盘,它将返回屏幕高度,该高度属于应用程序(screenHeight - statusBarHeight - keyboardHeight)。 - Vitaliy L
显示剩余2条评论

10

这个调用与你调用它的时间点无关:

...
Point dimensions = getDisplayDimensions(context);
int width = dimensions.x;
int height = dimensions.y;
...

@NonNull
public static Point getDisplayDimensions( Context context )
{
    WindowManager wm = ( WindowManager ) context.getSystemService( Context.WINDOW_SERVICE );
    Display display = wm.getDefaultDisplay();

    DisplayMetrics metrics = new DisplayMetrics();
    display.getMetrics( metrics );
    int screenWidth = metrics.widthPixels;
    int screenHeight = metrics.heightPixels;

    // find out if status bar has already been subtracted from screenHeight
    display.getRealMetrics( metrics );
    int physicalHeight = metrics.heightPixels;
    int statusBarHeight = getStatusBarHeight( context );
    int navigationBarHeight = getNavigationBarHeight( context );
    int heightDelta = physicalHeight - screenHeight;
    if ( heightDelta == 0 || heightDelta == navigationBarHeight )
    {
        screenHeight -= statusBarHeight;
    }

    return new Point( screenWidth, screenHeight );
}

public static int getStatusBarHeight( Context context )
{
    Resources resources = context.getResources();
    int resourceId = resources.getIdentifier( "status_bar_height", "dimen", "android" );
    return ( resourceId > 0 ) ? resources.getDimensionPixelSize( resourceId ) : 0;
}

public static int getNavigationBarHeight( Context context )
{
    Resources resources = context.getResources();
    int resourceId = resources.getIdentifier( "navigation_bar_height", "dimen", "android" );
    return ( resourceId > 0 ) ? resources.getDimensionPixelSize( resourceId ) : 0;
}

这个技巧在于它比较了屏幕显示指标(除了状态栏之外的内容)和“真实指标”,即设备的物理像素。

如果还没有减去状态栏的高度,那么将会特别减去。

(在我的测试中,包含返回和主页按钮的导航栏已经被减去了。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接