最近公司的项目中,需要判断出当前的虚拟导航栏NavigationBar是否存在,以及获取虚拟导航栏的高度。在网上查找了很多资料,比较靠谱的是以下方法(需要当前界面的视图被绘制完成后调用):
/**
* 检测底部虚拟导航栏是否存在
* @return
*/
public static boolean isNavigationBarExist(){
ViewGroup vp = (ViewGroup) CommonUtils.curActivity.getWindow().getDecorView();
if (vp != null) {
for (int i = 0; i < vp.getChildCount(); i++) {
vp.getChildAt(i).getContext().getPackageName();
if (vp.getChildAt(i).getId() != View.NO_ID
&& "navigationBarBackground".equals(CommonUtils.curActivity.getResources().getResourceEntryName(vp.getChildAt(i).getId()))) {
return true;
}
}
}
return false;
}
但是在某些机型上,比如公司的一台三星 Android 10.0以上系统的测试机,即使手机设置成全屏模式,将NavigationBar也选择了隐藏,该方法还是始终返回true。为此,又添加了下面这个方法加以处理:
/**
* 获取底部虚拟导航栏的高度
* @return
*/
public static int getNavigationBarHeight() {
int height = 0;
//屏幕实际尺寸
DisplayMetrics dm = new DisplayMetrics();
curActivity.getWindowManager().getDefaultDisplay().getRealMetrics(dm);
int phoneHeight = dm.heightPixels;
if (isNavigationBarExist()) {
Resources resources = CommonUtils.curActivity.getResources();
int resourceId = resources.getIdentifier("navigation_bar_height",
"dimen", "android");
if (resourceId > 0) {
//获取NavigationBar的高度
height = resources.getDimensionPixelSize(resourceId);
}
}
if (height > 0){
//处理全屏模式下,部分手机isNavigationBarExist()始终返回true,NavigationBar的高度
int diffValue = (CommonUtils.appScreenHeight + StatusBarUtil.getStatusBarHeight(curActivity) + height) - phoneHeight;
if (diffValue > 0){
height -= diffValue;
}
}
return height;
}
appScreenHeight 是除去状态栏的屏幕高度,可以在Activity的主界面通过设置addOnLayoutChangeListener监听处理:
view.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right,
int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
if (!isPause && (bottom - top) != (oldBottom - oldTop)) {
CommonUtils.appScreenHeight = bottom - top;
}
}
});
getStatusBarHeight是获取头部状态栏的高度,方法如下:
/**
* 获取状态栏高度
* @param context context
* @return 状态栏高度
*/
public static int getStatusBarHeight(Context context) {
// 获得状态栏高度
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
return context.getResources().getDimensionPixelSize(resourceId);
}