简体   繁体   English

获取半透明 Android 导航栏的位置和可见性

[英]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:然后,您可以计算以下插图:

  • Left: 0左:0
  • Top: value of status_bar_height顶部: status_bar_height
  • Right: 0 if navigation bar is not at bottom, else navigation_bar_width右:0 如果导航栏不在底部,否则为navigation_bar_width
  • Bottom: 0 if navigation bar is not at bottom, else: if orientation is landscape (see code above), 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 dp
  • navigation_bar_height : 48 dp navigation_bar_height栏高度:48 dp
  • navigation_bar_height_landscape : 48 dp navigation_bar_height_landscape栏高度景观:48 dp
  • navigation_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM