Android获取屏幕高度的坑

本周发现了一个坑:使用getResources().getDisplayMetrics().heightPixels获取屏幕高度的方法在某些全面屏手机以及带虚拟键手机上的高度不对,比目标高度小了十几个像素,因此做了个小调研。

安卓手机想要获取屏幕高度,有以下几个方法:

//1.这个网上比较少说到,一般会使用一个过时的方法getHeight
Point point = new Point();
getWindowManager().getDefaultDisplay().getSize(point);
point.y
//2.
DisplayMetrics outMetrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(outMetrics);
int height = outMetrics.heightPixels;
//3.上一种的小变式,区别在getRealMetrics
getWindowManager().getDefaultDisplay().getRealMetrics(dm);
 float height = dm.heightPixels;
//4.看起来比较简单的一种
float a = getResources().getDisplayMetrics().heightPixels;

第一个我们先不讲,因为实测和后面2、4基本一样,况且网上说的少用的也少

一开始我用的是方法4(因为他看起来最简单),发现在一些全面屏手机上高度会少了十几个像素,在普通手机上是准确的。
后来发现主要是虚拟按键的问题,getDisplayMetrics().heightPixels会将虚拟按键的高度忽略掉。点击去看到他的说明是The absolute height of the available display size in pixels.问题就在这个available上了。

同理,还有getMetrics方法,在Android4.4之后会隐藏掉状态栏的高度,注释里还写了一大堆,像来自Activity的请求在多窗口模式下会小于物理高度(这又是另一个坑了)

屏幕快照 2019-02-17 下午4.27.25.png

所以getRealMetrics是比较稳妥的一个方法,能够返回完整的屏幕参数。

之前还想到一种方法,在某些时机下主动隐藏虚拟键,这样不也能解决问题吗?
但是这样会有两个比较实际的问题:

  1. 某些手机的虚拟键是无法隐藏的,或者难以隐藏,比如我的魅族16p里有好几种切换模式,如果要做到完美,可能得花精力在部分机型的攻克上。
  2. 更加实际的,隐藏状态栏是肉眼不可见而已,上述方法返回值是不受影响的。
方便记忆

在参考文章1中,作者根据源码位置得到以下结论:

Context.getResources().getDisplayMetrics()依赖于手机系统,获取到的是系统的屏幕信息;
WindowManager.getDefaultDisplay().getMetrics(dm)是获取到Activity的实际屏幕信息。

个人觉得这个说法有点不够严谨,但是确实方便记忆,所以贴出来。

参考文章:

  1. https://blog.csdn.net/miehalu/article/details/52217345
  2. https://blog.csdn.net/mxthing/article/details/84823988
  3. https://xiaoyaozjl.iteye.com/blog/2178415

你可能感兴趣的:(Android获取屏幕高度的坑)