状态栏的高度?

有没有办法获得状态栏+标题栏的高度? 检查开发论坛显示相同的问题,但没有解决scheme(我可以find)。

我知道我们可以在初始布局之后得到它,但是我期待在我的活动的onCreate()中获得它。

谢谢

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

获取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; } 

虽然这是一个老问题,但我发现答案在onCreate()不起作用:

我从这里find了这个在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; } 

我希望这有助于任何人遇到这个问题。

对于像我这样想要在XML布局中使用它的人:

 <... android:layout_marginTop="@*android:dimen/status_bar_height" ... /> 

不要被Android Studio(2.2预览版3 – 在撰写的时候)所迷惑,不支持这个概念。 运行时确实。 我从Google的源代码中拿走了它。

我会build议下一个代码:

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

两个例子:

1)设备1品牌:三星,设备:maguro,板:金枪鱼,cpu_abi:armeabi-v7a,显示:ICL53F.M420KREL08,制造商:三星,型号:Galaxy Nexus,ver.release:4.0.2,ver.sdk:14 ;

屏幕分辨率:1280 x 720.该设备上没有硬件button。

结果:

 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; 

设备1的屏幕顶部有标题栏,屏幕底部有软件button的状态栏。

2)设备2设备:bravo,board:bravo,cpu_abi:armeabi-v7a,显示器:FRG83G,制造商:HTC,型号:HTC Desire,ver.release:2.2.2,ver.sdk:8,

屏幕分辨率:800 x 400.该设备有硬件button。

结果:

 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; 

设备2在屏幕的顶部有标题栏,根本没有状态栏。

上面提出了两个解决scheme:

 A) v.getTop() - rect.top 

这是不正确的设备1 – 它给出0而不是72)

 B) display.getHeight() - v.getHeight() 

这是不正确的设备2 – 它给出0而不是38)

变体:

  display.getHeight() - v.getBottom() + rect.top 

在两种情况下给出正确的结果。

更新

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 

设备3具有水平方向,在屏幕的顶部没有标题栏,并且在屏幕的底部具有状态栏。

所以在这里:

 int size_of_title_bar = rect.top; int size_of_status_bar = display.getHeight() - v.getBottom(); 

对于设备2和3是正确的。我不确定设备1.用户给我发送设备1的屏幕截图。在那里有一个带有软件button的状态栏。 但expression式“display.getHeight() – v.getBottom()”给出0。

在你的onCreate方法中将一个runnable附加到你的一个视图中,并把上面的代码放在那里。 这会使应用程序在连接到屏幕时计算状态栏+标题屏幕高度。

看看下面的代码:

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

如果这仍然没有办法,请尝试调用视图的postDelayed方法,而不是后期,并添加一个毫秒值作为第二个参数。

您也可以使用本博客文章所描述的方式,使用android的dimens.xml文件中的状态栏的维度。

这可以获得状态栏的高度而不需要等待绘图

我认为更好的方法来计算,即获得全屏的高度减去我们的主要布局

 phoneBarsHeight = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getHeight() - mainView.getHeight(); 

你可以把它放在onGlobalLayout() 。 这也适用于平板电脑,我尝试了Theme.NoTitleBar,但它必须始终工作。

也许你甚至可以通过改变mainView.getHeight()mainView.getMeasuredHeight()来增强它并使用onCreate() mainView.getMeasuredHeight()

Jorgesys发布的解决scheme非常好,但在onCreate()方法中不起作用。 我想这是因为状态栏和标题栏是在onCreate()之后创build的。

解决方法很简单 – 你应该把代码放在runnable中,并在onCreate()之后使用root.post((Runnable action) );

所以整个解决scheme:

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

我在这里find它

从API 23开始,获取状态栏高度有更好的解决scheme。 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; } 

请注意, getRootWindowInsets()将返回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) { } }); 

获得状态栏高度的支持方式是使用从API 21+开始的WindowInsets类:

 customView.setOnApplyWindowInsetsListener((view, insets) -> { // Handle insets return insets.consumeSystemWindowInsets(); }); 

WindowInsetsCompat支持库:

 ViewCompat.setOnApplyWindowInsetsListener(customView, (view, insets) -> { // Handle insets return insets.consumeSystemWindowInsets(); }); 

您也可以重写视图中的onApplyWindowInsets方法:

 public class CustomView extends View { @Override public WindowInsets onApplyWindowInsets(final WindowInsets insets) { final int statusBarHeight = insets.getStableInsetTop(); return insets.consumeStableInsets(); } } 

欲了解更多细节,我build议检查克里斯·巴恩斯谈话 – 成为主窗口钳工 (幻灯片在这里可用)。