Reliably get height of status bar to solve KitKat translucent navigation issue
Asked Answered
A

4

27

I am experimenting with the new Android 4.4 translucent navigation bars and would like to set the navigation bar as translucent using the FLAG_TRANSLUCENT_NAVIGATION flag. I only wish the navigation bar (back, home button etc) to be translucent - I want the status bar at the top of the screen to appear normally I.e. NOT translucent.

The code I am using to achieve this is:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    Window w = getWindow();
    w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}

The problem I have is Android now thinks the Activity is fullscreen and places the layout behind the navigation bar (which is correct), unfortunately it also places the layout behind the status bar (a problem).

A hacky fix for this would be to apply a padding to the top of the layout parent View, however I need to determine the height of the status bar to do this.

Could anyone suggest how I get the status bar height, it's not as trivial as I thought it would be, or alternatively suggest a proper solution.

Thanks

Accumulative answered 14/12, 2013 at 14:12 Comment(2)
Hi Milo, I'm facing the same problem here. I've tried this workaround but my Layout keeps behind my ActionBAr. I've added a top padding to my root layout but I think the Status Bar height is not enough, do you have the same problem? I need to set a top padding for both heigths?Angeliaangelic
Noni, I get the root view of the Activity as follows: getWindow().getDecorView().findViewById(android.R.id.content); I then apply padding I.e. setPadding(0, statusBarHeight, 0, 0); Hope that helps.Accumulative
H
61
public int getStatusBarHeight() {
      int result = 0;
      int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
      if (resourceId > 0) {
          result = getResources().getDimensionPixelSize(resourceId);
      }
      return result;
}

Use the above code in the onCreate method. Put it in a contextWrapper class. http://mrtn.me/blog/2012/03/17/get-the-height-of-the-status-bar-in-android/

Hoopen answered 14/12, 2013 at 14:17 Comment(7)
This does seem to work, do you know if this will work on every Android version 4.1 and above? I do remember reading this solution may not work on Transformer tablets, it makes me wonder if this'll fail on other devices too?Accumulative
its only for the transformer tablet as far as i know. Works fine on other devices that i have tested. And dont forget to accept and upvote. cheersHoopen
It's a pity there isn't a reliable method to get the height of the status bar on every device. That said, it'll have to do for now.Accumulative
Yea that only because its not available publicly to the developers as part of the API. Its just a hack for getting around it. Hopefully there will be a official support for the next SDK release.Hoopen
just to add, the height is basically 25dip. I checked the source. However, the guidelines give the Status bar 24dp google.com/design/spec/layout/…Enfilade
Height is 24dp in Marshmellow+Poetize
On Galaxy s10 is the statusbar wider, because of the camera holePriestess
P
25

Since api 21 there is official method for retrieving insets for status bar and navigation bar height when is translucent

ViewCompat.setOnApplyWindowInsetsListener(view, new OnApplyWindowInsetsListener() {
        @Override
        public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
            final int statusBar = insets.getSystemWindowInsetTop();
            final int navigationBar = insets.getSystemWindowInsetBottom();
            return insets;
        }
    });
Poe answered 5/1, 2016 at 15:1 Comment(5)
Super useful! The only thing that works as expected in multi window mode with Android 7.0.Smidgen
that kind of view is "view"?Repairman
I'd love to see more documentation / information on this. getSystemWindowInsetTop() seems like such a weird name for "status bar height".Keratinize
This is a little tricky because Google assumed the status bar is not always above your content (Remember Android Honeycomb UI?). The same with the navigation bar - it can appear on the right when you rotate the screen. You shouldn't care where they are, the system will tell you where you should apply your paddings. Look here for more information, read this article: medium.com/google-developers/…Poe
Somehow, the onApplyWindowInsets() is not triggered in my case. I set this inside onCreateView() in a fragment. Do you have any clue?Eckard
G
3

The accepted answer always returns the status bar height (and in a somewhat hacky way). But some activities may actually be fullscreen, and this method doesn't differentiate between them.

This method works perfectly for me to find the status bar height relative to the current activity (place it in your Activity class, and use it once layout has finished):

public int getStatusBarHeight() {
    Rect displayRect = new Rect();
    getWindow().getDecorView().getWindowVisibleDisplayFrame(displayRect);
    return displayRect.top;
}

Note you could also just use displayRect directly in case you have other "window decorations" at the bottom or potentially even the sides of the screen.

Gradus answered 16/2, 2016 at 15:7 Comment(1)
This works for 10.1 WXGA table emulator which in API 16 does not display a status bar because it puts status info in bottom nav bar. Still looking for a way to determine status bar height and/or display status before layout.Ellieellinger
V
0

recommend to use this script to get the status bar height

Rect rectangle = new Rect();
Window window = getWindow();
window.getDecorView().getWindowVisibleDisplayFrame(rectangle);
int statusBarHeight = rectangle.top;
int contentViewTop = 
    window.findViewById(Window.ID_ANDROID_CONTENT).getTop();
int titleBarHeight= contentViewTop - statusBarHeight;

   Log.i("*** Elenasys :: ", "StatusBar Height= " + statusBarHeight + " , TitleBar Height = " + titleBarHeight); 

(old Method) to get the Height of the status bar on the onCreate() method of your Activity, use this method:

public int getStatusBarHeight() { 
      int result = 0;
      int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
      if (resourceId > 0) {
          result = getResources().getDimensionPixelSize(resourceId);
      } 
      return result;
}
Vicky answered 4/8, 2016 at 10:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.