我正在开发一个已移植到Android的跨平台应用程序。由于其非Android遗产,因此未广泛使用Android UI元素-主应用程序窗口是单个View
。
我想实现KitKat之前所支持的半透明系统(状态和导航)栏,同时确保主View
内部的UI元素不会被它们阻塞。
This answer显示如何获取这些栏的默认高度(横向模式下导航栏的高度也为navigation_bar_height_landscape
,垂直导航栏的宽度为navigation_bar_width
)。但是,这些只是系统的默认大小,如果当前显示的是导航栏,以及它是显示在屏幕的右侧还是底部,则不包含任何信息。
到目前为止,我发现的其他答案对于非半透明的系统栏可能效果很好:它们只是将屏幕总大小与主应用程序视图的大小进行比较,不同之处在于系统栏所占的空间。但是,对于半透明的系统栏,大小差异为零,并且该方法不起作用。
如何可靠地确定是否显示导航栏以及显示在哪个位置?
环顾四周,包括AOSP代码的this part,我想到了以下内容:
// 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);
}
然后您可以计算以下插图:
status_bar_height
的值navigation_bar_width
navigation_bar_height_landscape
;其他navigation_bar_height
。根据dimens.xml的默认值为:
status_bar_height
:24 dpnavigation_bar_height
:48 dpnavigation_bar_height_landscape
:48 dpnavigation_bar_width
:48 dp((如果不知何故无法获得实际值,您可能希望使用这些方法。)>
isNavShowing
的逻辑是对我不久前实现的东西的变体。它甚至可以在运行CyanogenMod的OnePlusOne上可靠地检测到物理菜单按钮的存在(用户可以在其中通过“设置”在导航栏和硬件按钮之间进行切换)。即使将软件“菜单”按钮添加到导航栏(这似乎是CM的附加功能),仍可以正确检测到导航栏。
isNavAtBottom
的逻辑主要来自我上面链接的源文件中的findNavigationBar()
函数,并且除非您使用的是高度定制的Android版本,否则它应该可以工作。