[英]Get position and visibility of translucent Android navigation bar
I'm working on a cross-platform app which has been ported to Android.我正在开发一个已移植到 Android 的跨平台应用程序。 Due to its non-Android heritage it doesn't make extensive use of Android UI elements – the main app window is one single View
.由于其非 Android 传统,它没有大量使用 Android UI 元素——主应用程序窗口是一个单一的View
。
I would like to implement translucent system (status and navigation) bars, as supported from KitKat onwards, while ensuring that UI elements inside the main View
are not obstructed by them.我想实现从 KitKat 开始支持的半透明系统(状态和导航)栏,同时确保主View
内的 UI 元素不会被它们挡住。
This answer shows how to get the default height for these bars (there is also navigation_bar_height_landscape
for navigation bar height in landscape mode, and navigation_bar_width
for the width of a vertical navigation bar).这样的回答显示了如何获取这些条默认高度(也有navigation_bar_height_landscape
在横向模式下导航栏的高度,并navigation_bar_width
的垂直导航栏的宽度)。 But these are only the system's default sizes and contain no information if the navigation bar is currently being shown, and whether it is showing at the right or on the bottom edge of the screen.但这些只是系统的默认尺寸,不包含导航栏当前是否正在显示,以及它是显示在屏幕右侧还是底部边缘的信息。
The other answers I have found so far probably work fine for non-translucent system bars: they simply compare total screen size to the size of the main app view, and the difference is the space occupied by the system bars.到目前为止,我发现的其他答案可能适用于非半透明系统栏:它们只是将总屏幕大小与主应用程序视图的大小进行比较,不同之处在于系统栏占用的空间。 However, with translucent system bars, the size difference is zero and this approach won't work.但是,对于半透明的系统条,大小差异为零,这种方法不起作用。
How can I reliably determine if the navigation bar is being displayed, and in which position?如何可靠地确定导航栏是否正在显示,以及在哪个位置?
Looking around a bit, including this part of the AOSP code, I came up with the following:环顾四周,包括这部分AOSP 代码,我想出了以下内容:
// determine if navigation bar is going to be shown
boolean isNavShowing;
if (Build.VERSION.SDK_INT >= 13) {
isNavShowing = ViewConfiguration.get(activity.getApplication()).hasPermanentMenuKey();
}
// determine where the navigation bar would be displayed
boolean isNavAtBottom;
if (Build.VERSION.SDK_INT >= 13) {
isNavAtBottom = (activity.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE)
|| (activity.getResources().getConfiguration().smallestScreenWidthDp >= 600);
}
You can then calculate the following insets:然后,您可以计算以下插图:
status_bar_height
顶部: status_bar_height
值navigation_bar_width
右:0 如果导航栏不在底部,否则为navigation_bar_width
navigation_bar_height_landscape
;底部:0 如果导航栏不在底部,否则:如果方向是横向(见上面的代码), navigation_bar_height_landscape
; else navigation_bar_height
.否则navigation_bar_height
。Defaults, as per dimens.xml , are:根据dimens.xml 的默认值是:
status_bar_height
: 24 dp status_bar_height
: 24 dpnavigation_bar_height
: 48 dp navigation_bar_height
栏高度:48 dpnavigation_bar_height_landscape
: 48 dp navigation_bar_height_landscape
栏高度景观:48 dpnavigation_bar_width
: 48 dp navigation_bar_width
栏宽度:48 dp(you might want to fall back to these if somehow you fail to get the actual values.) (如果您以某种方式未能获得实际值,您可能希望回到这些。)
The logic for isNavShowing
is a variation on something I implemented a while ago. isNavShowing
的逻辑是我不久前实现的东西的变体。 It reliably detects the presence of a physical Menu button even on a OnePlusOne running CyanogenMod (where the user can switch between a navigation bar and hardware buttons via Settings).即使在运行 CyanogenMod 的 OnePlusOne 上(用户可以通过设置在导航栏和硬件按钮之间切换),它也能可靠地检测到物理菜单按钮的存在。 Even when adding a software Menu button to the navigation bar (which seems to be a CM addition), the navigation bar is still detected correctly.即使在导航栏中添加了软件菜单按钮(这似乎是一个CM添加),仍然可以正确检测到导航栏。
The logic for isNavAtBottom
is mostly taken from the findNavigationBar()
function in the source file I linked above and should work unless you are using a heavily customized build of Android. isNavAtBottom
的逻辑主要取自我上面链接的源文件中的findNavigationBar()
函数,除非您使用高度定制的 Android 版本,否则应该可以使用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.