Android中状态栏的高度

时间:2010-08-04 15:44:16

标签: android statusbar

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

根据我的测量结果,它似乎是25dp,但我不确定它是否在所有平台上具有相同的高度。

(我想知道这是为了正确实现从没有状态栏的活动到具有状态栏的活动的淡入淡出过渡)

23 个答案:

答案 0 :(得分:339)

这个问题之前得到了回答...... Height of statusbar?

<强>更新 ::

当前方法:

好的,状态栏的高度取决于屏幕尺寸,例如在设备中 屏幕尺寸为240 X 320,状态栏高度为20px,对于屏幕尺寸为320 X 480的设备,状态栏高度为25px,对于480 x 800的设备,状态栏高度必须为38px

所以我建议使用此脚本来获取状态栏高度

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); 

(旧方法)获取Activity的onCreate()方法的状态栏的高度,使用此方法:

public int getStatusBarHeight() { 
      int result = 0;
      int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
      if (resourceId > 0) {
          result = getResources().getDimensionPixelSize(resourceId);
      } 
      return result;
} 

答案 1 :(得分:197)

在用于获取状态栏高度的所有代码示例中,实际上似乎在onCreate Activity方法中工作的唯一代码是:

public int getStatusBarHeight() {
    int result = 0;
    int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
    if (resourceId > 0) {
        result = getResources().getDimensionPixelSize(resourceId);
    }
    return result;
}

显然,状态栏的实际高度保留为Android资源。上述代码可以添加到ContextWrapper类(例如Activity)。

找到http://mrtn.me/blog/2012/03/17/get-the-height-of-the-status-bar-in-android/

答案 2 :(得分:48)

在MDPI设备上,状态栏为25px。我们可以使用它作为基础并将其乘以密度(向上舍入)以获得任何设备上的状态栏高度:

int statusBarHeight = Math.ceil(25 * context.getResources().getDisplayMetrics().density);

供参考:ldpi = .75,mdpi = 1,hdpi = 1.5,xhdpi = 2

答案 3 :(得分:33)

硬编码大小或使用反射来获取sizeof(int)的值被认为是不好的做法。克里斯巴恩斯talked about this in at the Droidcon New York。获取状态栏大小的推荐方法是通过OnApplyWindowInsetsListener

status_bar_height

这是在API 20中添加的,也是通过ViewAppCompat向后移植的。

答案 4 :(得分:30)

我已经将一些解决方案合并在一起:

public static int getStatusBarHeight(final Context context) {
    final Resources resources = context.getResources();
    final int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
    if (resourceId > 0)
        return resources.getDimensionPixelSize(resourceId);
    else
        return (int) Math.ceil((VERSION.SDK_INT >= VERSION_CODES.M ? 24 : 25) * resources.getDisplayMetrics().density);
    }

另一种选择:

    final View view = findViewById(android.R.id.content);
    runJustBeforeBeingDrawn(view, new Runnable() {
        @Override
        public void run() {
            int statusBarHeight = getResources().getDisplayMetrics().heightPixels - view.getMeasuredHeight();
        }
    });

编辑:runJustBeforeBeingDrawn的替代方案:https://stackoverflow.com/a/28136027/878126

答案 5 :(得分:25)

根据Google design guidelines;状态栏的高度为24 dp。

如果您想获得状态栏高度(以像素为单位),可以使用以下方法:

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

可以通过以下活动调用:

statusBarHeight(getResources());

答案 6 :(得分:18)

这也适用于参考link

public int getStatusBarHeight() {
  int result = 0;
  int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
  if (resourceId > 0) {
      result = getResources().getDimensionPixelSize(resourceId);
  }
  return result;
}

答案 7 :(得分:13)

我有同样的问题,必须在onCreate中获取状态栏高度。这对我有用。

private static final int LOW_DPI_STATUS_BAR_HEIGHT = 19;

private static final int MEDIUM_DPI_STATUS_BAR_HEIGHT = 25;

private static final int HIGH_DPI_STATUS_BAR_HEIGHT = 38;

在onCreate中:

DisplayMetrics displayMetrics = new DisplayMetrics();
((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(displayMetrics);

int statusBarHeight;

switch (displayMetrics.densityDpi) {
    case DisplayMetrics.DENSITY_HIGH:
        statusBarHeight = HIGH_DPI_STATUS_BAR_HEIGHT;
        break;
    case DisplayMetrics.DENSITY_MEDIUM:
        statusBarHeight = MEDIUM_DPI_STATUS_BAR_HEIGHT;
        break;
    case DisplayMetrics.DENSITY_LOW:
        statusBarHeight = LOW_DPI_STATUS_BAR_HEIGHT;
        break;
    default:
        statusBarHeight = MEDIUM_DPI_STATUS_BAR_HEIGHT;
}

请参阅:

http://developer.android.com/reference/android/util/DisplayMetrics.html http://developer.android.com/guide/practices/ui_guidelines/icon_design.html

答案 8 :(得分:13)

官方身高是24dp, 正如Google在Android Design webpage上正式声明的那样。

答案 9 :(得分:12)

是的,当我尝试使用View时,它提供了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);
            }
        }
    }
}

答案 10 :(得分:12)

默认高度曾经是25dp。使用Android Marshmallow(API 23),高度降低到24dp。

答案 11 :(得分:9)

  

240x320 - 20px

     

320x480 - 25px

     

480x800 + - 38px

答案 12 :(得分:6)

试试这个:

    Rect rect = new Rect();
    Window win = this.getWindow();
    win.getDecorView().getWindowVisibleDisplayFrame(rect);
    int statusBarHeight = rect.top;
    int contentViewTop = win.findViewById(Window.ID_ANDROID_CONTENT).getTop();
    int titleBarHeight = contentViewTop - statusBarHeight;
    Log.d("ID-ANDROID-CONTENT", "titleBarHeight = " + titleBarHeight );

它在活动的onCreate方法中对我不起作用,但是当我将它放在onClickListener并给我测量25时

答案 13 :(得分:4)

为了解决这个问题,我使用了一种组合方法。 这是必要的,因为在平板电脑上系统栏已经在调用display.getHeight()时减去它的像素。 所以我首先检查是否存在系统栏,然后Ben Claytons接近,这在手机上运行良好。

public int getStatusBarHeight() {
    int statusBarHeight = 0;

    if (!hasOnScreenSystemBar()) {
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            statusBarHeight = getResources().getDimensionPixelSize(resourceId);
        }
    }

    return statusBarHeight;
}

private boolean hasOnScreenSystemBar() {
    Display display = getWindowManager().getDefaultDisplay();
    int rawDisplayHeight = 0;
    try {
        Method getRawHeight = Display.class.getMethod("getRawHeight");
        rawDisplayHeight = (Integer) getRawHeight.invoke(display);
    } catch (Exception ex) {
    }

    int UIRequestedHeight = display.getHeight();

    return rawDisplayHeight - UIRequestedHeight > 0;
}

答案 14 :(得分:4)

状态栏的高度在android 6.0中是24dp

 <!-- Height of the status bar -->
 <dimen name="status_bar_height">24dp</dimen>
 <!-- Height of the bottom navigation / system bar. -->
 <dimen name="navigation_bar_height">48dp</dimen>

你可以在源代码中找到答案:frameworks \ base \ core \ res \ res \ values \ dimens.xml

答案 15 :(得分:3)

结合两个最佳解决方案的Kotlin版本

fun getStatusBarHeight(): Int {
    val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
    return if (resourceId > 0) resources.getDimensionPixelSize(resourceId)
    else Rect().apply { window.decorView.getWindowVisibleDisplayFrame(this) }.top
}
  1. 获取status_bar_height值(如果存在)
  2. 如果不存在status_bar_height,请根据“窗口装饰”计算状态栏的高度

答案 16 :(得分:2)

在Android 4.1及更高版本中,您可以将应用程序的内容设置为显示在状态栏后面,以便在状态栏隐藏和显示时不会调整内容的大小。为此,请使用SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN。您可能还需要使用SYSTEM_UI_FLAG_LAYOUT_STABLE来帮助您的应用程序保持稳定的布局。

当您使用此方法时,您有责任确保应用程序UI的关键部分(例如,地图应用程序中的内置控件)最终不会被系统栏覆盖。这可能会使您的应用无法使用。在大多数情况下,您可以通过将android:fitsSystemWindows属性添加到XML布局文件来设置为true来处理此问题。这会调整父ViewGroup的填充以为系统窗口留出空间。这对于大多数应用来说已经足够了。

但是,在某些情况下,您可能需要修改默认填充以获得所需的应用布局。要直接操作内容相对于系统栏(占据窗口的“内容插入”空间)的内容,请覆盖fitSystemWindows(Rect insets)。当窗口的内容插入已更改时,视图层次结构将调用fitSystemWindows()方法,以允许窗口相应地调整其内容。通过重写此方法,您可以根据需要处理插入(以及应用程序的布局)。

形式: https://developer.android.com/training/system-ui/status.html#behind

答案 17 :(得分:2)

切换全屏解决方案:

此解决方案可能看起来像一种解决方法,但它实际上会说明您的应用是否是全屏(也就是隐藏状态栏):

Display display = getWindowManager().getDefaultDisplay();
Point size = new Point(); display.getSize(size);
int barheight = size.y - findViewById(R.id.rootView).getHeight();

这样,如果您的应用目前是全屏,barheight将等于0。

就个人而言,我必须使用它来纠正绝对的TouchEvent坐标,以便对状态栏进行说明:

@Override
public boolean onTouch(View view,MotionEvent event) {
    Display display = getWindowManager().getDefaultDisplay();
    Point size = new Point(); display.getSize(size);
    int YCoord = (int)event.getRawY() - size.y + rootView.getHeight());
}

这将获得绝对的y坐标,无论应用是否全屏。

享受

答案 18 :(得分:2)

由于现在可以使用多窗口模式,因此您的应用程序顶部可能没有状态栏。

以下解决方案将自动为您处理所有案件。

android:fitsSystemWindows="true"

或以编程方式

findViewById(R.id.your_root_view).setFitsSystemWindows(true);

您还可以通过

获得根视图
findViewById(android.R.id.content).getRootView();
or
getWindow().getDecorView().findViewById(android.R.id.content)

有关获取根视图的更多详细信息,请参考-https://stackoverflow.com/a/4488149/9640177

答案 19 :(得分:1)

顶部答案对某些人不起作用的原因是因为在准备渲染之前无法获取视图的尺寸。实际可以使用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
        }
    }
}

这是最可靠的方法。

答案 20 :(得分:1)

如果您确切知道尺寸VS高度

例如,在屏幕尺寸为320 X 480的设备中,状态栏高度为25px,对于480 x 800的设备,状态栏高度必须为38px

然后您可以获得视图的宽度/屏幕大小,您只需使用if else语句来获取状态栏的高度

答案 21 :(得分:0)

由于我的Pixel 3XL出现缺口,这个问题最近对我来说很重要。我真的很喜欢enter image description here,但是我希望能够随意获取状态栏的高度,因为这对于我需要播放的全屏动画特别有必要。以下功能启用了可靠的查询:

val newMatrix = buildOrthographicMatrix(1f / scaleFactor, 1f / scaleFactor * height / width, 30f, 0.01f)
camera.projectionMatrix = Matrix(newMatrix)

private fun buildOrthographicMatrix(right: Float, top: Float, far: Float, near: Float): FloatArray {
   val matrix = FloatArray(16)
   matrix[0] = 1 / right
   matrix[1] = 0f
   matrix[2] = 0f
   matrix[3] = 0f
   matrix[4] = 0f
   matrix[5] = 1 / top
   matrix[6] = 0f
   matrix[7] = 0f
   matrix[8] = 0f
   matrix[9] = 0f
   matrix[10] = -2 / (far - near)
   matrix[11] = 0f
   matrix[12] = 0f
   matrix[13] = 0f
   matrix[14] = -(far + near) / (far - near)
   matrix[15] = 1f
   return matrix
}

然后在活动类中:

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

您当然希望将活动的弱引用传递给静态Helper类方法参数,但是为了简洁起见,本示例中省略了。出于相同的原因,省略了fun blurView() { this.runOnUiThread { Helper.blurView(this) } } blurBitmap,因为它们与获取状态栏的高度不直接相关。

答案 22 :(得分:0)

感谢@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#转换而来,但这只是公正的。适用于缺口等。