最近在做一个项目,绘制一个自定义View,距离屏幕底部 XXdp,在占满全屏的父布局里的 onLayout() 回调方法中对该自定义 View 进行位置布局,Y 轴的坐标算法如下:
val mViewYPosition = Utils.getScreenHeight() - mView.measureHeight - bottomMargin
其中获取手机屏幕高度的工具方法如下:
private int sScreenHeight = 0
public static int getScreenHeight() {
if (sScreenHeight != 0) {
return sScreenHeight;
}
WindowManager wm = (WindowManager) mAppContext.getSystemService(Context.WINDOW_SERVICE);
if (wm != null && wm.getDefaultDisplay() != null) {
DisplayMetrics outMetrics = new DisplayMetrics();
Display display = wm.getDefaultDisplay();
display.getMetrics(outMetrics);
switch (display.getRotation()) {
case Surface.ROTATION_0:
case Surface.ROTATION_180://fall through
sScreenHeight = outMetrics.heightPixels;
sScreenWidth = outMetrics.widthPixels;
break;
case Surface.ROTATION_90:
case Surface.ROTATION_270://fall through
sScreenHeight = outMetrics.widthPixels;
sScreenWidth = outMetrics.heightPixels;
break;
}
return sScreenHeight;
} else {
return 1080;
}
}
复制代码
实际测试发现,在不同安卓机型上该自定义 View 距离底部的高度是明显不一致的。
最后通过排查发现,不同机型的屏幕高度获取方式是不一样的:
- 比如在小米 note3(Android 9, 物理导航栏) 这种机型,screenHeight 就是最终的屏幕高度
- 而小米10的最终屏幕高度是 screenHeight + statusBarHeight + navigationBarHeight
因此,最佳做法是直接获取当前这个全屏父布局的高度, 一下列出错误方式和准确方式:
- 错误方式
var totalScreenHeight = DeviceTool.getStatusBarHeight() + DeviceTool.getScreenHeight()
+ DeviceTool.getNavigationBarHeight() //错误方式
复制代码
- 准确方式
var totalScreenHeight = measuredHeight //正确方式(注意获取measureHeight 的时机,此处只是示例)
复制代码
这里提供一种查看屏幕分辨率的快捷命令:
adb shell wm size
打印如下: