最近公司的項目中,需要判斷出當前的虛擬導航欄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);
}