Android中状态栏的高度

hpi*_*que 314 android statusbar

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

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

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

Jor*_*sys 353

这个问题之前得到了解答...... 状态栏的高度?

更新 ::

目前的方法:

好的,状态栏的高度取决于屏幕尺寸,例如在屏幕尺寸为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); 
Run Code Online (Sandbox Code Playgroud)

(旧方法)获取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;
} 
Run Code Online (Sandbox Code Playgroud)

  • 或者使用dip?如果它总是有25dip则不需要代码. (16认同)
  • 你不能认为它总是25dp(例如在点燃火上检查高度). (8认同)
  • 如果你处于多窗口模式+纵向旋转+第二个窗口,`window.getDecorView().getWindowVisibleDisplayFrame(rectangle)`不是获取状态栏高度的正确方法.你将获得巨大的价值(包括第一高度). (3认同)

Ben*_*ton 204

在我用来获取状态栏高度的所有代码示例中,实际看起来在onCreatean方法中工作的唯一一个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;
}
Run Code Online (Sandbox Code Playgroud)

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

发现于http://mrtn.me/blog/2012/03/17/get-the-height-of-the-status-bar-in-android/

  • 需要注意的是 - 这并不适用于所有设备.例如,在Transformer TF201(以及TF101,TF300和其他一些设备)上,高度报告为25,其中没有状态栏. (6认同)
  • 根据上面的评论,在我看来,代码告诉你状态栏在特定设备上的高度 - 而不是特定活动(实际上可能没有状态栏)的状态. (4认同)

Gra*_*hew 48

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

int statusBarHeight = Math.ceil(25 * context.getResources().getDisplayMetrics().density);
Run Code Online (Sandbox Code Playgroud)

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

  • 对于*具有*状态栏的设备,这是正确的.请注意,由于上面写了,所以并非所有设备都有一个.具体而言,运行ICS的设备可能在底部具有组合状态/导航栏,而在顶部则没有任何内容.因此,对于大多数编程目的,您可能希望将高度零指定给状态栏,但上述公式将为您提供非零大小. (6认同)
  • 小修正:ldpi = 0.75.+1正确答案 (3认同)

Nik*_*las 41

硬编码大小或使用反射来获得值status_bar_height被认为是不好的做法.Chris Banes 在Droidcon纽约谈到了这一点.获取状态栏大小的推荐方法是通过OnApplyWindowInsetsListener:

myView.setOnApplyWindowInsetsListener { view, insets -> {
  val statusBarSize = insets.systemWindowInsetTop
  return insets
}
Run Code Online (Sandbox Code Playgroud)

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

  • 然而这个API太可怕了,因为幕后的WTF/Gotchas数量巨大.你认为你可以用任何视图来做,但不,你需要覆盖某些东西,并确保你将插件传递给你的孩子(??),因为一些ViewGroups(材料设计)和所有其他人不会(线性布局?ConstraintLayout?你好?).而不是系统有一个Window.getStatusBarSize()...我们必须订阅一个疯狂的听众...回家Android,你喝醉了.只是硬编码直到谷歌醒来,我们在2018年.我希望克里斯巴恩斯看到这一天... (53认同)
  • `insets.systemWindowInsetTop` 现已弃用。因此,现在获取状态栏插入的最实际方法是:“val statusbarInsets = insets.getInsets(WindowInsetsCompat.Type.statusBars())”,然后是“statusbarInsets.top”。详细了解如何在实现边到边时使用插图处理重叠 https://developer.android.com/training/gestures/edge-to-edge#handle-overlaps (4认同)

and*_*per 33

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

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);
    }
Run Code Online (Sandbox Code Playgroud)

另一种选择:

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

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


Ras*_*hid 26

根据谷歌设计指南 ; 状态栏的高度为24 dp.

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

private static int statusBarHeight(android.content.res.Resources res) {
    return (int) (24 * res.getDisplayMetrics().density);
}
Run Code Online (Sandbox Code Playgroud)

可以通过以下活动调用:

statusBarHeight(getResources());
Run Code Online (Sandbox Code Playgroud)

  • 直到棉花糖它是25dp.从棉花糖开始,它是24dp. (18认同)
  • 这本质上是对值进行硬编码 - 不允许设计更改 (2认同)
  • 这是最新的链接:https://material.io/design/platform-guidance/android-bars.html#status-bar (2认同)

Par*_*han 18

这也适用于参考链接

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


cry*_*sxd 15

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

  • 甜的!我刚刚专门为 API 级别 23+ 制作了一个 dimens.xml,其中我将高度硬编码为 24dp。 (2认同)

ben*_*lau 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;
Run Code Online (Sandbox Code Playgroud)

在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;
}
Run Code Online (Sandbox Code Playgroud)

看到:

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

  • 硬编码这些值是危险的,如果它们在以后的平台版本中发生变化会怎么样? (5认同)
  • 我喜欢你使用密度驱动值的想法.如果您要在多个地方使用代码(或使用其他与密度相关的值),我更喜欢将工作卸载到系统,并将值存储在维度资源中,这使得切换不必要.您需要为每个密度创建特定于维度的文件夹和资源文件.final资源res = context.getResources(); int statusbarHeight = 0; 尝试{statusbarHeight = res.getDimensionPixelSize(R.dimen.android_statusbar_height); } catch(NotFoundException e){} (3认同)

Joa*_*huk 13

24dp正如Google在Android Design网页上正式声明的那样官方身高.


小智 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);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Den*_*nis 9

240x320 - 20px

320x480 - 25px

480x800 + - 38px

  • 这不再准确。使用一种测量状态栏的方法。 (3认同)

tom*_*ozb 8

结合两个最佳解决方案的 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
}
Run Code Online (Sandbox Code Playgroud)
  1. 注意到status_bar_height值(如果存在)
  2. 如果status_bar_height不存在,则根据 Window 装饰计算状态栏高度


Mar*_*tyn 7

试试这个:

    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 );
Run Code Online (Sandbox Code Playgroud)

它在活动的onCreate方法中对我没有用,但当我把它放在onClickListener并给我测量25时


Rut*_*ger 6

为了解决这个问题,我使用了组合方法。这是必要的,因为在平板电脑上,当 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;
}
Run Code Online (Sandbox Code Playgroud)


小智 5

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>
Run Code Online (Sandbox Code Playgroud)

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

  • 有没有办法在我们的 XML 中获取此资源?`@android:dimen/status_bar_height` 对我不起作用 (2认同)