Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get status bar height dynamically from XML

I need to optimize my Android app to look good on phones with a notch, like the Essential Phone.

This phones have different status bar heights than the standard 25dp value, so you can't hardcode that value.

The Android P developer preview released yesterday includes support for the notch and some APIs to query its location and bounds, but for my app I only need to be able to get the status bar height from XML, and not use a fixed value.

Unfortunately, I couldn't find any way to get that value from XML.

Is there any way?

Thank you.

like image 986
fergaral Avatar asked Mar 08 '18 10:03

fergaral


4 Answers

I have already found the answer:

The recommended way is to use the WindowInsets API, like the following:

view.setOnApplyWindowInsetsListener { v, insets -> 
    view.height = insets.systemWindowInsetTop // status bar height
    insets
}

Accessing the status_bar_height, as it's a private resource and thus subject to change in future versions of Android, is highly discouraged.

like image 141
fergaral Avatar answered Nov 09 '22 22:11

fergaral


It is not a solution, but it can explain you how it should be don in correct way and how things are going under the hood: https://www.youtube.com/watch?v=_mGDMVRO3iE

OLD SOLUTION:

Here is small trick:

@*android:dimen/status_bar_height

android studio will show you an error, but it will work like a charm :)

like image 26
Andriy Antonov Avatar answered Nov 09 '22 21:11

Andriy Antonov


Method provides the height of status bar

public int getStatusBarHeight() {
  int result = 0;
  int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
 if (resourceId > 0) {
  result = getResources().getDimensionPixelSize(resourceId);
}   
 return result;
}
like image 6
Harpz Avatar answered Nov 09 '22 22:11

Harpz


class StatusBarSpacer @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
View(context, attrs) {
private var statusHeight: Int = 60

init {
    if (context is Activity && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
        context.window.decorView.setOnApplyWindowInsetsListener { _, insets ->
            statusHeight = insets.systemWindowInsetTop
            requestLayout()
            insets
        }
        context.window.decorView.requestApplyInsets()
    } else statusHeight = resources.getDimensionPixelSize(
        resources.getIdentifier("status_bar_height", "dimen", "android")
    )
}

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) =
    setMeasuredDimension(0, statusHeight)
}
like image 3
Skotos Avatar answered Nov 09 '22 23:11

Skotos