Android中状态栏的高度

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

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

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

423937 次浏览

试试这个:

    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的测量

这个问题在… 状态栏的高度? < / p >

更新::

当前的方法:

好吧,状态栏的高度取决于屏幕的大小,例如在一个设备中 对于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);

(旧方法)在你的活动的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;
}

如果你知道它的大小和高度

就像

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

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

240x320 - 20px

320x480 - 25px

480x800+ - 38px

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

我有同样的问题,必须在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 < / p >

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

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

参考参数:ldpi=。75, mdpi=1, hdpi=1.5, xhdpi=2

在我用来获取状态栏高度的所有代码示例中,唯一在ActivityonCreate方法中实际工作的代码示例是:

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/找到

这也适用于引用链接

public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
为了解决这个问题,我使用了一种组合方法。 这是必要的,因为在平板电脑上,当调用display.getHeight()时,系统栏已经减去了它的像素。 所以我首先检查系统栏是否存在,然后本克莱顿方法,这在手机上很有效。< / p >
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;
}

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

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的替代方案

切换全屏解决方案:

这个解决方案可能看起来像一个变通方法,但它实际上解释了你的应用程序是否全屏(也就是隐藏状态栏):

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坐标无论应用是否全屏。

享受

官方高度是24dp, 正如谷歌在Android设计网页上正式声明的那样。< / p >

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

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

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

可以从activity中调用:

statusBarHeight(getResources());

上面的答案对某些人不起作用的原因是,在视图准备好渲染之前,您无法获得视图的维度。如果可以的话,使用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
}
}
}

这是最可靠的方法。

默认高度是25dp。在Android Marshmallow (API 23)中,高度降低到24dp。

更新:请注意,自从缺口和打孔的时代开始,使用静态高度的状态栏不再工作。请使用窗口插页代替!

在android6.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\ dimensions .xml

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

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

然而,在某些情况下,你可能需要修改默认填充来获得你的应用程序所需的布局。要直接操作你的内容如何相对于系统栏布局(占据一个空间称为窗口的“内容insets”),覆盖fitSystemWindows(矩形insets)。fitSystemWindows()方法在窗口的内容嵌入发生变化时由视图层次结构调用,以允许窗口相应地调整其内容。通过重写这个方法,你可以随心所欲地处理嵌入(因此你的应用程序的布局)。

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

硬编码大小或使用反射来获取status_bar_height的值被认为是不好的做法。Chris Banes 在纽约Droidcon大会上讨论过这个问题。获取状态栏大小的推荐方法是通过OnApplyWindowInsetsListener:

myView.setOnApplyWindowInsetsListener { view, insets -> {
val statusBarSize = insets.systemWindowInsetTop
return insets
}

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

这个问题最近与我有关,因为我的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类方法参数,但为了简洁起见,我在本例中没有这样做。出于同样的原因,__abc0和errorHudFrameLayout被省略了,因为它们与获取状态栏的高度没有直接关系。

感谢@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#转换,但这是它的公正。工作与缺口等。

由于多窗口模式现在是可用的,你的应用程序可能没有状态栏在顶部。

以下解决方案为您自动处理所有情况。

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

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不存在,则从Window decor计算状态栏高度