平常我们做开发的时候,常用的方法就是获取屏幕宽高,但是真正的屏幕宽高是什么,顾名思义,屏幕的宽是屏幕的宽,但是屏幕的高到底是指哪一部分的高,整体的高?还是显示区域的高,此时屏幕的高是指包括导航栏和状态栏吗,还是不包括,如果没有系统导航栏的时候,屏幕的高是指哪,如果有导航栏呢?没有具体的定义,所以,我总结了一些屏幕高度方法.
/**
* 通过反射拿到屏幕实际的高度(包括状态栏和导航栏),获取的是正常竖屏的高
*/
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;
}
以上方法是自己总结的,每个方法都有说明,这里就不再具体说明了。