Android 状态栏的高度?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3355367/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Height of statusbar?
提问by user291701
Is there a way to get the height of the statusbar + titlebar? Checking the dev forum shows the same question but no solution (that I could find).
有没有办法获取状态栏+标题栏的高度?检查开发论坛显示了相同的问题,但没有解决方案(我能找到)。
I know we can get it after the initial layout pass, but I'm looking to get it in onCreate() of my activity.
我知道我们可以在初始布局通过后获得它,但我希望在我的活动的 onCreate() 中获得它。
Thanks
谢谢
回答by Jorgesys
Rect rectgle= new Rect();
Window window= getWindow();
window.getDecorView().getWindowVisibleDisplayFrame(rectgle);
int StatusBarHeight= rectgle.top;
int contentViewTop=
window.findViewById(Window.ID_ANDROID_CONTENT).getTop();
int TitleBarHeight= contentViewTop - StatusBarHeight;
Log.i("*** Jorgesys :: ", "StatusBar Height= " + StatusBarHeight + " , TitleBar Height = " + TitleBarHeight);
Get the Height of the status bar on the onCreate()
method of your Activity, use this method:
在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;
}
回答by Aleksey Gureiev
For those, like me, who want to use it in your XML layouts:
对于像我这样想在 XML 布局中使用它的人:
<...
android:layout_marginTop="@*android:dimen/status_bar_height"
... />
Don't be confused by that Android Studio (2.2 Preview 3 -- at the moment of writing) doesn't support this notion. The runtime does. I took it from the Google's source code.
不要被 Android Studio(2.2 预览版 3——在撰写本文时)不支持这个概念所迷惑。运行时确实如此。我从谷歌的源代码中获取了它。
回答by raukodraug
Although this is an old question, I found that the answer didn't work in onCreate()
:
虽然这是一个老问题,但我发现答案在onCreate()
以下情况下不起作用:
I found this code from herewhich does work in the onCreate()
method
我从这里找到了这段代码,它在该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;
}
I hope this helps to anyone that runs into this issue.
我希望这对遇到此问题的任何人都有帮助。
回答by yarq
The supported way of getting status bar height is to use WindowInsets
class starting from API 21+:
支持的获取状态栏高度的方法是使用WindowInsets
从 API 21+ 开始的类:
customView.setOnApplyWindowInsetsListener((view, insets) -> {
// Handle insets
return insets.consumeSystemWindowInsets();
});
or WindowInsetsCompat
for support libraries:
或WindowInsetsCompat
支持库:
ViewCompat.setOnApplyWindowInsetsListener(customView, (view, insets) -> {
// Handle insets
return insets.consumeSystemWindowInsets();
});
You can also override the onApplyWindowInsets
method inside the view:
您还可以覆盖onApplyWindowInsets
视图内的方法:
public class CustomView extends View {
@Override
public WindowInsets onApplyWindowInsets(final WindowInsets insets) {
final int statusBarHeight = insets.getStableInsetTop();
return insets.consumeStableInsets();
}
}
For further details, I'd recommend checking Chris Banes talk - Becoming a master window fitter(slides available here).
有关更多详细信息,我建议您查看 Chris Banes 谈话 - Becoming a master window fitter(此处提供幻灯片)。
回答by dvpublic
I would suggest next code:
我建议下一个代码:
Rect rect = new Rect();
Window window = activity.getWindow();
if (window != null) {
window.getDecorView().getWindowVisibleDisplayFrame(rect);
android.view.View v = window.findViewById(Window.ID_ANDROID_CONTENT);
android.view.Display display = ((android.view.WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
//return result title bar height
return display.getHeight() - v.getBottom() + rect.top;
}
Two examples:
两个例子:
1) Device 1 brand: samsung, device: maguro, board: tuna, cpu_abi: armeabi-v7a, display: ICL53F.M420KREL08, manufacturer: samsung, model: Galaxy Nexus, ver.release: 4.0.2, ver.sdk: 14;
1) 设备 1 品牌:samsung,设备:maguro,主板:tuna,cpu_abi:armeabi-v7a,显示器:ICL53F.M420KREL08,制造商:samsung,型号:Galaxy Nexus,ver.release:4.0.2,ver.sdk:14 ;
Screen resolution: 1280 x 720.There are no hardware buttons on this device.
屏幕分辨率:1280 x 720。此设备上没有硬件按钮。
Results:
结果:
rect: left=0 right=720 top=72 bottom=1208;
v: left=0 right=720 top=72 bottom=1208;
display: height=1208 width=720;
correct result=72;
Device 1 has title bar at the top of the screen and status bar with software buttons at the bottom of the screen.
设备 1 在屏幕顶部有标题栏,在屏幕底部有带有软件按钮的状态栏。
2) Device 2 device: bravo, board: bravo, cpu_abi: armeabi-v7a, display: FRG83G, manufacturer: HTC, model: HTC Desire, ver.release: 2.2.2, ver.sdk: 8,
2) Device 2 device: bravo, board: bravo, cpu_abi: armeabi-v7a, display: FRG83G, 厂商: HTC, 型号: HTC Desire, ver.release: 2.2.2, ver.sdk: 8,
Screen resolution: 800 x 400. This device has hardware buttons.
屏幕分辨率:800 x 400。此设备具有硬件按钮。
Results:
结果:
rect: left=0 right=480 top=38 bottom=800;
v: left=0 right=480 top=0 bottom=800;
display: height=800 width=480;
correct result: phone_bar_height=38;
Device 2 has title bar at the top of the screen and hasn't status bar at all.
设备 2 在屏幕顶部有标题栏,根本没有状态栏。
Two solutions were suggested above:
上面提出了两种解决方案:
A) v.getTop() - rect.top
(it is incorrect for device 1- it gives 0 instead of 72)
(设备 1 不正确- 它给出 0 而不是 72)
B) display.getHeight() - v.getHeight()
(it is incorrect for device 2- it gives 0 instead of 38)
(设备 2 不正确- 它给出 0 而不是 38)
Variant:
变体:
display.getHeight() - v.getBottom() + rect.top
gives correct results in both cases.
在这两种情况下都给出正确的结果。
Update
更新
3) One more example (third device): brand: LGE, device: v909, cpu_abi: armeabi-v7a, display: HMJ37, model: LG-V909, ver.release: 3.1, ver.sdk: 12
3)再举一个例子(第三个设备):品牌:LGE,设备:v909,cpu_abi:armeabi-v7a,显示器:HMJ37,型号:LG-V909,ver.release:3.1,ver.sdk:12
rect: left=0 right=1280 top=0 bottom=720
v: left=0 right=1280 top=0 bottom=720
Display: height=768 width=1280
phone_bar_height=48
Device 3 has horizontal orientation, hasn't title bar at the top of the screen and has status bar at the bottom of the screen.
设备 3 为水平方向,屏幕顶部没有标题栏,屏幕底部有状态栏。
So, here:
所以在这里:
int size_of_title_bar = rect.top;
int size_of_status_bar = display.getHeight() - v.getBottom();
It's correct for devices 2 and 3. I am not sure about device 1. User sent me screenshot of device 1. There is a status bar with software button there. But expression "display.getHeight() - v.getBottom()" gives 0.
它适用于设备 2 和 3。我不确定设备 1。用户给我发送了设备 1 的屏幕截图。那里有一个带有软件按钮的状态栏。但是表达式“display.getHeight() - v.getBottom()”给出0。
回答by LKallipo
You could also take the dimension of the status bar found in the dimens.xml file of android using the way that this blog postdescribes.
您还可以使用此博客文章描述的方式获取在 android 的 dimens.xml 文件中找到的状态栏的尺寸。
This can get the height of the statusbar without the need to wait for drawing.
这样就可以获取状态栏的高度,而无需等待绘制。
Quoting the code from the blog post:
引用博文中的代码:
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
You need to put this method in a ContextWrapper class.
您需要将此方法放在 ContextWrapper 类中。
回答by Kachi
Attach a runnable to one of your views in your onCreate method, and place the above code in there. This will cause the application to calculate the status bar + titlescreen height when they are attached to the screen.
在您的 onCreate 方法中将一个 runnable 附加到您的一个视图,并将上面的代码放在那里。这将导致应用程序在附加到屏幕时计算状态栏 + 标题屏幕高度。
Take a look at the code below:
看看下面的代码:
myView.post(new Runnable() {
@Override
public void run() {
Rect rectgle= new Rect();
Window window= getWindow();
window.getDecorView().getWindowVisibleDisplayFrame(rectgle);
int StatusBarHeight= rectgle.top;
int contentViewTop= window.findViewById(Window.ID_ANDROID_CONTENT).getTop();
int TitleBarHeight= contentViewTop - StatusBarHeight;
}
});
If this still doesn't do the trick, try invoking the view's postDelayed method instead of post and adding a millisecond value as the second argument.
如果这仍然不能解决问题,请尝试调用视图的 postDelayed 方法而不是 post 并添加一个毫秒值作为第二个参数。
回答by Mikooos
I think better way to calculate that is to get height of fullscreen minus our main layout
我认为更好的计算方法是获得全屏高度减去我们的主要布局
phoneBarsHeight = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getHeight()
- mainView.getHeight();
And you can put it in onGlobalLayout()
. This works on tablets too, I tried it on Theme.NoTitleBar, but it must always works.
你可以把它放进去onGlobalLayout()
。这也适用于平板电脑,我在 Theme.NoTitleBar 上尝试过,但它必须始终有效。
Maybe you can even enhance it and use it onCreate()
by changing mainView.getHeight()
to mainView.getMeasuredHeight()
.
也许您甚至可以onCreate()
通过更改mainView.getHeight()
为 来增强它并使用它mainView.getMeasuredHeight()
。
回答by jakkubu
The solution posted by Jorgesys is very good, but it doesn't work inside onCreate() method. I guess it's because statusbar and titlebar are created after onCreate().
Jorgesys 发布的解决方案非常好,但它在 onCreate() 方法中不起作用。我猜这是因为状态栏和标题栏是在 onCreate() 之后创建的。
The solution is easy - you should put code inside runnable and execute it after onCreate() by using root.post((Runnable action) );
解决方案很简单 - 您应该将代码放入 runnable 并在 onCreate() 之后使用 root.post((Runnable action) );
So the whole solution:
所以整个解决方案:
root = (ViewGroup)findViewById(R.id.root);
root.post(new Runnable() {
public void run(){
Rect rectgle= new Rect();
Window window= getWindow();
window.getDecorView().getWindowVisibleDisplayFrame(rectgle);
int StatusBarHeight= rectgle.top;
int contentViewTop=
window.findViewById(Window.ID_ANDROID_CONTENT).getTop();
int TitleBarHeight= contentViewTop - StatusBarHeight;
Log.i("*** jakkubu :: ", "StatusBar Height= " + StatusBarHeight +
" , TitleBar Height = " + TitleBarHeight);
}
});
I find it here
我在这里找到
回答by Clyde
As of API 23 there is a better solution to getting the status bar height. API 23 adds a WindowInsets
feature, so you can use this code to get the size of the system insets, in this case at the top.
从 API 23 开始,有一个更好的解决方案来获取状态栏高度。API 23 添加了一项WindowInsets
功能,因此您可以使用此代码获取系统插图的大小,在本例中位于顶部。
public int getStatusBarHeight() {
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
return binding.mainContent.getRootWindowInsets().getStableInsetTop();
}
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if(resourceId != 0) {
return getResources().getDimensionPixelSize(resourceId);
}
return 0;
}
Note that getRootWindowInsets()
will return null until after the View has been attached to a Window so it can't be used directly in onCreate()
but you can add a listener for the window attach and do it there - here I am adding the status bar inset to the size of my toolbar, which I hide and show, along with the status bar. When it's shown, I want the status bar over the top of it so I add the status bar height to the toolbar's top padding.
请注意,getRootWindowInsets()
在 View 附加到 Window 之前将返回 null,因此它不能直接在其中使用,onCreate()
但您可以为窗口附加添加一个侦听器并在那里执行 - 在这里我将状态栏插入到大小我隐藏和显示的工具栏以及状态栏。当它显示时,我希望状态栏位于它的顶部,因此我将状态栏高度添加到工具栏的顶部填充。
binding.mainContent.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View view) {
binding.toolbar.setPadding(binding.toolbar.getPaddingLeft(),
binding.toolbar.getPaddingTop() + getStatusBarHeight(),
binding.toolbar.getPaddingRight(), binding.toolbar.getPaddingBottom());
binding.mainContent.removeOnAttachStateChangeListener(this);
}
@Override
public void onViewDetachedFromWindow(View view) {
}
});