可靠获取状态栏高度解决KitKat半透明导航问题
Posted
技术标签:
【中文标题】可靠获取状态栏高度解决KitKat半透明导航问题【英文标题】:Reliably get height of status bar to solve KitKat translucent navigation issue 【发布时间】:2014-01-02 06:34:25 【问题描述】:我正在试验新的 android 4.4 半透明导航栏,并希望使用 FLAG_TRANSLUCENT_NAVIGATION
标志将导航栏设置为半透明。我只希望导航栏(返回、主页按钮等)是半透明的 - 我希望屏幕顶部的状态栏正常显示,即不透明。
我用来实现这一点的代码是:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
Window w = getWindow();
w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
我遇到的问题是 Android 现在认为 Activity 是全屏的,并将布局放在导航栏后面(这是正确的),不幸的是它也将布局放在状态栏后面(有问题)。
对此的一个 hacky 解决方法是将填充应用到布局父视图的顶部,但是我需要确定状态栏的高度来执行此操作。
谁能建议我如何获得状态栏高度,它并不像我想象的那么简单,或者建议一个适当的解决方案。
谢谢
【问题讨论】:
嗨,Milo,我在这里遇到了同样的问题。我已经尝试过这种解决方法,但我的布局仍然落后于我的 ActionBAr。我在我的根布局中添加了一个顶部填充,但我认为状态栏高度不够,你有同样的问题吗?我需要为两个高度设置一个顶部填充? Noni,我得到Activity的根视图如下:getWindow().getDecorView().findViewById(android.R.id.content);然后我应用填充即setPadding(0, statusBarHeight, 0, 0);希望对您有所帮助。 【参考方案1】: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 方法中使用上面的代码。将它放在 contextWrapper 类中。 http://mrtn.me/blog/2012/03/17/get-the-height-of-the-status-bar-in-android/
【讨论】:
这似乎可行,您知道这是否适用于所有 Android 4.1 及更高版本?我记得读过这个解决方案可能不适用于 Transformer 平板电脑,这让我想知道这是否也会在其他设备上失败? 据我所知,它仅适用于变压器平板电脑。在我测试过的其他设备上运行良好。并且不要忘记接受和投票。欢呼 遗憾的是没有可靠的方法来获取每个设备上状态栏的高度。也就是说,现在必须这样做。 是的,只是因为它不能作为 API 的一部分公开提供给开发人员。它只是绕过它的一个技巧。希望下一个 SDK 版本会有官方支持。 只是补充一下,高度基本是25dip。我检查了来源。但是,指南给状态栏 24dp google.com/design/spec/layout/…【参考方案2】:从 api 21 开始,有官方方法可以在半透明时检索状态栏和导航栏高度的插图
ViewCompat.setOnApplyWindowInsetsListener(view, new OnApplyWindowInsetsListener()
@Override
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets)
final int statusBar = insets.getSystemWindowInsetTop();
final int navigationBar = insets.getSystemWindowInsetBottom();
return insets;
);
【讨论】:
超级好用!在 Android 7.0 的多窗口模式下唯一能按预期工作的东西。 那种视图是“视图”? 我很想看到更多关于此的文档/信息。getSystemWindowInsetTop()
似乎是“状态栏高度”的奇怪名称。
这有点棘手,因为 Google 假设状态栏并不总是在您的内容之上(还记得 Android Honeycomb UI 吗?)。导航栏也是如此 - 当您旋转屏幕时,它会出现在右侧。你不应该关心它们在哪里,系统会告诉你应该在哪里应用你的填充。在这里查看更多信息,阅读这篇文章:medium.com/google-developers/…
不知何故,onApplyWindowInsets()
在我的情况下没有被触发。我在片段的 onCreateView() 中设置了它。你有什么线索吗?【参考方案3】:
接受的答案总是返回状态栏高度(并且以一种有点老套的方式)。但有些活动实际上可能是全屏的,这种方法并不能区分它们。
这个方法非常适合我找到相对于当前活动的状态栏高度(将它放在你的 Activity 类中,并在布局完成后使用它):
public int getStatusBarHeight()
Rect displayRect = new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(displayRect);
return displayRect.top;
请注意,您也可以直接使用 displayRect,以防您在底部或什至可能是屏幕两侧有其他“窗口装饰”。
【讨论】:
这适用于 10.1 WXGA 表模拟器,它在 API 16 中不显示状态栏,因为它将状态信息放在底部导航栏中。仍在寻找一种方法来确定状态栏高度和/或显示状态之前布局。【参考方案4】:建议使用此脚本获取状态栏高度
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);
(旧方法)在你的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;
【讨论】:
以上是关于可靠获取状态栏高度解决KitKat半透明导航问题的主要内容,如果未能解决你的问题,请参考以下文章
利用 Android 4.4 KitKat 中的半透明状态栏
利用 Android 4.4 KitKat 中的半透明状态栏