平常我們做開發的時候,常用的方法就是獲取屏幕寬高,但是真正的屏幕寬高是什麼,顧名思義,屏幕的寬是屏幕的寬,但是屏幕的高到底是指哪一部分的高,整體的高?還是顯示區域的高,此時屏幕的高是指包括導航欄和狀態欄嗎,還是不包括,如果沒有系統導航欄的時候,屏幕的高是指哪,如果有導航欄呢?沒有具體的定義,所以,我總結了一些屏幕高度方法.
/**
* 通過反射拿到屏幕實際的高度(包括狀態欄和導航欄),獲取的是正常豎屏的高
*/
public int getScreenRealHeight() {
int dpi = 0;
Display display = ((Activity) mContext).getWindowManager().getDefaultDisplay();
DisplayMetrics dm = new DisplayMetrics();
@SuppressWarnings("rawtypes")
Class c;
try {
c = Class.forName("android.view.Display");
@SuppressWarnings("unchecked")
Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);
method.invoke(display, dm);
if (isScreenLandscape()) {
dpi = dm.widthPixels;
} else {
dpi = dm.heightPixels;
}
} catch (Exception e) {
e.printStackTrace();
}
if (dpi == 0) {
if (isScreenLandscape()) {
dpi = getScreenWidth();
} else {
if (ImmersionBar.hasNotchScreen((Activity) mContext)) {
dpi = getScreenAvailableHeight() + getNotchHeight() + getNavigationBarHeight();
} else {
dpi = getScreenAvailableHeight() + getStatusBarHeight() + getNavigationBarHeight();
}
}
}
return dpi;
}
/**
* 計算屏幕可用高度(如果底部導航欄顯示,高度爲底部導航欄上到頂部狀態欄下,如果底部導航欄不顯示,高度爲屏幕底部到頂部狀態欄下)
*/
public int getScreenAvailableHeight() {
Rect rect = new Rect();
mWindow.getDecorView().getWindowVisibleDisplayFrame(rect);
if (isScreenLandscape()) {
return rect.right - rect.left;
} else {
return rect.bottom - rect.top;
}
}
/**
* 獲取導航欄虛擬按鍵的高度,如果虛擬按鍵隱藏就返回0,否則返回虛擬按鍵的高度
*/
public int getNavigationBarHeight() {
if (isNavigationBarShow()) {
return calculateNavigationBarHeight();
} else {
mNavigationBarHeight = 0;
return mNavigationBarHeight;
}
}
/**
* 計算虛擬按鍵的高度
*/
private int calculateNavigationBarHeight() {
if (mNavigationBarHeight == 0) {
try {
Class<?> clazz = Class.forName("com.android.internal.R$dimen");
Object object = clazz.newInstance();
int height = Integer.parseInt(clazz.getField("navigation_bar_height").get(object).toString());
mNavigationBarHeight = mContext.getResources().getDimensionPixelSize(height);
} catch (Exception e) {
e.printStackTrace();
}
}
if (mNavigationBarHeight == 0) {
Resources res = mContext.getResources();
int resourceId = res.getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0) {
mNavigationBarHeight = res.getDimensionPixelSize(resourceId);
}
}
if (mNavigationBarHeight == 0) {
Rect rect = new Rect();
mWindow.getDecorView().getWindowVisibleDisplayFrame(rect);
Point realSize = new Point();
mWindowManager.getDefaultDisplay().getRealSize(realSize);
mNavigationBarHeight = realSize.y - rect.bottom;
}
return mNavigationBarHeight;
}
/**
* 判斷虛擬導航欄是否顯示
*
* @return true(顯示虛擬導航欄),false(不顯示或不支持虛擬導航欄)
*/
public boolean isNavigationBarShow() {
//判斷小米手機是否開啓了全面屏,開啓了,直接返回false
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (Settings.Global.getInt(mContext.getContentResolver(), "force_fsg_nav_bar", 0) != 0) {
return false;
}
}
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN_MR1) {
int screenRealHeight = getScreenRealHeight();
int statusBarHeight = getStatusBarHeight();
int screenAvailableHeight = getScreenAvailableHeight();
return screenAvailableHeight + statusBarHeight < screenRealHeight;
} else {
//其他手機根據屏幕真實高度與顯示高度是否相同來判斷
Display d = mWindowManager.getDefaultDisplay();
DisplayMetrics realDisplayMetrics = new DisplayMetrics();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
d.getRealMetrics(realDisplayMetrics);
}
int realHeight = realDisplayMetrics.heightPixels;
int realWidth = realDisplayMetrics.widthPixels;
DisplayMetrics displayMetrics = new DisplayMetrics();
d.getMetrics(displayMetrics);
int displayHeight = displayMetrics.heightPixels;
int displayWidth = displayMetrics.widthPixels;
return (realWidth - displayWidth) > 0 || (realHeight - displayHeight) > 0;
}
}
/**
* 判斷當前屏幕方向是否爲橫屏
*
* @return true 橫屏 false 豎屏
*/
public boolean isScreenLandscape() {
Configuration mConfiguration = mContext.getResources().getConfiguration(); //獲取設置的配置信息
int ori = mConfiguration.orientation; //獲取屏幕方向
return ori == Configuration.ORIENTATION_LANDSCAPE;
}
以上方法是自己總結的,每個方法都有說明,這裏就不再具體說明了。