Android中状态栏的高度是多少?总是一样吗?

从我的测量来看,它似乎是25dp,但我不确定它是否在所有平台上都有相同的高度。

(我想知道这正确地实现一个淡出过渡从一个没有状态栏的活动到一个这样做)


当前回答

感谢@Niklas +1,这是正确的方法。

public class MyActivity extends Activity implements android.support.v4.View.OnApplyWindowInsetsListener {

    Rect windowInsets;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.my_activity);

        View rootview = findViewById(android.R.id.content);

        android.support.v4.View.ViewCompat.setOnApplyWindowInsetsListener(rootview, this);
    }

    android.support.v4.View.WindowInsetsCompat android.support.v4.View.OnApplyWindowInsetsListener.OnApplyWindowInsets(View v, android.support.v4.View.WindowInsetsCompat insets)
    {
        windowInsets = new Rect();
        windowInsets.set(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(), insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom());
        //StatusBarHeight = insets.getSystemWindowInsetTop();

        //Refresh/Adjust view accordingly

        return insets;
    }
}

请原谅,如果代码不是100%正确,从Xamarin c#转换,但这是它的公正。工作与缺口等。

其他回答

这个问题最近与我有关,因为我的Pixel 3XL上的缺口。我真的很喜欢android开发者的解决方案,但我希望能够随心所欲地获得状态栏的高度,因为这对于我需要播放的全屏动画是特别必要的。下面的函数启用了一个可靠的查询:

private val DEFAULT_INSET = 96
fun getInsets(view: View?): Int {
     var inset = DEFAULT_INSET
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//Safe because only P supports notches
          inset = view?.rootWindowInsets?.stableInsetTop ?: DEFAULT_INSET
     }
     return inset
}

fun blurView(rootView: View?, a: SpacesActivity?) {
    val screenBitmap = getBitmapFromView(rootView!!)
    val heightDifference = getInsets(rootView)
    val croppedMap = Bitmap.createBitmap(
                    screenBitmap, 0, heightDifference,
                    screenBitmap.width,
                    screenBitmap.height - heightDifference)
    val blurredScreen = blurBitmap(croppedMap)
    if (blurredScreen != null) {
         val myDrawable = BitmapDrawable(a!!.resources, blurredScreen)
         a.errorHudFrameLayout?.background = myDrawable
         a.appBarLayout?.visibility = View.INVISIBLE
   }
}

然后在活动课上

fun blurView() {
    this.runOnUiThread {
        Helper.blurView(this)
    }
}

您当然希望将活动的弱引用传递给静态Helper类方法参数,但为了简洁起见,我在本例中没有这样做。由于同样的原因,blurbitmap和errorHudFrameLayout被省略了,因为它们并不直接与获取状态栏的高度有关。

上面的答案对某些人不起作用的原因是,在视图准备好渲染之前,您无法获得视图的维度。使用一个OnGlobalLayoutListener来获得所说的维度,当你实际上可以:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final ViewGroup decorView = (ViewGroup) this.getWindow().getDecorView();
    decorView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            if (Build.VERSION.SDK_INT >= 16) {
                decorView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            } else {
                // Nice one, Google
                decorView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            }
            Rect rect = new Rect();
            decorView.getWindowVisibleDisplayFrame(rect);
            rect.top; // This is the height of the status bar
        }
    }
}

这是最可靠的方法。

感谢@Niklas +1,这是正确的方法。

public class MyActivity extends Activity implements android.support.v4.View.OnApplyWindowInsetsListener {

    Rect windowInsets;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.my_activity);

        View rootview = findViewById(android.R.id.content);

        android.support.v4.View.ViewCompat.setOnApplyWindowInsetsListener(rootview, this);
    }

    android.support.v4.View.WindowInsetsCompat android.support.v4.View.OnApplyWindowInsetsListener.OnApplyWindowInsets(View v, android.support.v4.View.WindowInsetsCompat insets)
    {
        windowInsets = new Rect();
        windowInsets.set(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(), insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom());
        //StatusBarHeight = insets.getSystemWindowInsetTop();

        //Refresh/Adjust view accordingly

        return insets;
    }
}

请原谅,如果代码不是100%正确,从Xamarin c#转换,但这是它的公正。工作与缺口等。

是的,当我尝试使用视图时,它提供了25px的结果。 以下是整个代码:

public class SpinActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LinearLayout lySpin = new LinearLayout(this);
        lySpin.setOrientation(LinearLayout.VERTICAL);       
        lySpin.post(new Runnable()
        {
            public void run()
            {
                Rect rect = new Rect();
                Window window = getWindow();
                window.getDecorView().getWindowVisibleDisplayFrame(rect);
                int statusBarHeight = rect.top;
                int contentViewTop = 
                    window.findViewById(Window.ID_ANDROID_CONTENT).getTop();
                int titleBarHeight = contentViewTop - statusBarHeight;
                System.out.println("TitleBarHeight: " + titleBarHeight 
                    + ", StatusBarHeight: " + statusBarHeight);
            }
        }
    }
}

根据材料指南;状态栏高度为24dp。

如果你想获得状态栏的高度,你可以使用下面的方法:

private static int statusBarHeight(android.content.res.Resources res) {
    return (int) (24 * res.getDisplayMetrics().density);
}

可以从activity中调用:

statusBarHeight(getResources());