状态栏的高度?
有没有办法获得状态栏+标题栏的高度? 检查开发论坛显示相同的问题,但没有解决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议检查克里斯·巴恩斯谈话 – 成为主窗口钳工 (幻灯片在这里可用)。