// retrieve the position of the DecorView
Rect visibleFrame = new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(visibleFrame);
DisplayMetrics dm = getResources().getDisplayMetrics();
// check if the DecorView takes the whole screen vertically or horizontally
boolean isRightOfContent = dm.heightPixels == visibleFrame.bottom;
boolean isBelowContent = dm.widthPixels == visibleFrame.right;
public static boolean hasNavBar (Resources resources)
{
int id = resources.getIdentifier("config_showNavigationBar", "bool", "android");
if (id > 0)
return resources.getBoolean(id);
else
return false;
}
public static int getNavigationBarHeight (Resources resources)
{
if (!Utils.hasNavBar(resources))
return 0;
int orientation = resources.getConfiguration().orientation;
//Only phone between 0-599 has navigationbar can move
boolean isSmartphone = resources.getConfiguration().smallestScreenWidthDp < 600;
if (isSmartphone && Configuration.ORIENTATION_LANDSCAPE == orientation)
return 0;
int id = resources
.getIdentifier(orientation == Configuration.ORIENTATION_PORTRAIT ? "navigation_bar_height" : "navigation_bar_height_landscape", "dimen", "android");
if (id > 0)
return resources.getDimensionPixelSize(id);
return 0;
}
public static int getNavigationBarWidth (Resources resources)
{
if (!Utils.hasNavBar(resources))
return 0;
int orientation = resources.getConfiguration().orientation;
//Only phone between 0-599 has navigationbar can move
boolean isSmartphone = resources.getConfiguration().smallestScreenWidthDp < 600;
if (orientation == Configuration.ORIENTATION_LANDSCAPE && isSmartphone)
{
int id = resources.getIdentifier("navigation_bar_width", "dimen", "android");
if (id > 0)
return resources.getDimensionPixelSize(id);
}
return 0;
}
boolean navBarOnTheBottom(){
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int viewHeight = displaymetrics.heightPixels;
if (bkg.getHeight() == viewHeight)
{
Log.d(TAG, "nav bar on the side");
return false;
}
else{
Log.d(TAG, "nav bar on the bottom");
return true;
}
}
7条答案
按热度按时间jk9hmnmh1#
部分基于Pauland的回答(反过来基于
PhoneWindowManager
的实现),下面是我目前使用的代码:这在Nexus 7 2012和Nexus 4上都有效,这两款手机都运行Android 5.1。
在具有永久MENU键的设备上,没有系统栏。根据您的使用情况,您可能需要检查这种情况:
(其中
ctxt
是某个Context
)就我个人而言,我使用这个来尝试将滑动面板放在系统栏的相反轴上,因为在系统栏一侧的边框滑动有点难以触发。我不会使用这个或任何其他算法(如依赖于
getDecorView()
的算法)来处理任何关键问题。7cwmlq892#
通过结合使用decor视图的属性和当前的DisplayMetrics,您可以找出导航栏位于哪一侧。
vltsax253#
我的解决方案
基于https://android.googlesource.com/platform/frameworks/base/+/9f65c4c34abb07bdda54649ed510af26f16e9c1b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java的解决方案
798qvoo84#
我的工作解决方案是:
fbcarpbf5#
这是我的应用程序,我用这个半透明的状态栏和导航栏来设置填充。
bkg它是保存我所有应用视图的主linearLayout。请确保bkg.getHeight()不会给予你0,对于某些布局,它确实给了我0
**EDIT:**如果上面的值为0,则获取如下布局高度
bq8i3lrv6#
请注意,从Android 7.1开始,导航栏也可能位于屏幕的左侧。为了确保您始终知道导航栏的位置,请使用
DisplayListener
检查Android 7.1及更高版本的180°屏幕变化,如下所示:How to detect screen rotation through 180 degrees from landscape to landscape orientation?我已经成功而可靠地使用了以下代码来确定导航栏位置的任何更改:
请记住,将已处于横向模式的设备旋转180°时,Activity不会重新创建,因此在
onNavigationBarMoved
中,landscapeScreenRotation
的值会告诉您何时发生这种情况,以便您相应地重新调整UI。qmelpv7a7#
所有现有的答案都不适用于
FLAG_LAYOUT_NO_LIMITS
。我找到了一个新的解决方案:下面是sysbottom、sysstop、sysleft、sysright -导航栏和状态栏的系统栏缩进值(以像素为单位)。