获取屏幕宽,高的方法,包括考虑到通知栏,导航栏等等

平常我们做开发的时候,常用的方法就是获取屏幕宽高,但是真正的屏幕宽高是什么,顾名思义,屏幕的宽是屏幕的宽,但是屏幕的高到底是指哪一部分的高,整体的高?还是显示区域的高,此时屏幕的高是指包括导航栏和状态栏吗,还是不包括,如果没有系统导航栏的时候,屏幕的高是指哪,如果有导航栏呢?没有具体的定义,所以,我总结了一些屏幕高度方法.

 

/**
	 * 通过反射拿到屏幕实际的高度(包括状态栏和导航栏),获取的是正常竖屏的高
	 */
	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;
	}

以上方法是自己总结的,每个方法都有说明,这里就不再具体说明了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章