Display metrics minus status bar?

The biggest trick to all of this is that you can't usually gain access to a true value of that view's size until layout is complete. Which means onCreate() (and often onResume() also) are too early in the process to do the calculation. The following code will get you a view representing the content view of the Activity, at which point you can examine its height and width:

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

This also accounts for any title views you may have set in the Activity. You could also obtain a reference to the root layout you set as the content view when the XML is inflated and do the same thing if that layout is set to fill_parent in both dimensions.

A good method where I often make calls like this is onWindowFocusChanged() which will be called at the point when your Activity is just about visible to the user.

Hope that Helps!


This call is independent of the point of time you call it:

...
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;
}

The trick is that it compares the screen display metrics (what you want modulo the status bar) and the "real metrics", which is the physical pixels of the device.

The status bar height then is subtracted ad-hoc if that did not happen yet.

(In my tests the navigation bar, containing back and home buttons, was already subtracted.)

Tags:

Android