项目中需要做一个接近全屏尺寸的dialog,但是要比状态栏和工具栏低。
所以弹窗的宽度为屏幕宽度,高度为屏幕高度-状态栏高度-工具栏高度。当按着逻辑写完时,发现运行在小米8A手机上显示不正确,比需要的高度更低,但是在三星S7上没问题。因为我获取屏幕高度的方式是:
DisplayMetrics localDisplayMetrics = new DisplayMetrics();
windowManager.getDefaultDisplay()
.getMetrics(localDisplayMetrics);
使用localDisplayMetrics 的heightPixels字段作为屏幕高度。经调试发现,该手机实际分辨率为1520*720,获取到的 localDisplayMetrics的heightPixels为1369:
截屏2020-05-1315.02.15.png
同时又看到 logicalHeight 是1520,也就是正确的屏幕高度。所以就打算改为windowManager.getDefaultDisplay()
.getRealSize()方法获取到logicalHeight。同时看到有这样的两个字段:
largestNominalAppWidth和largestNominalAppHeight。意为“名义上的最大宽度”和“名义上的最大高度”。这两个值应该是包括了横屏和竖屏的情况考虑后的值。
在小米8A上 这些字段的值为
appWidth = 720
appHeight = 1369
largestNominalAppWidth = 1369
largestNominalAppHeight = 1465
logicalHeight = 1520
logicalWidth = 720
在三星S7edge上的值为
appWidth = 1440
appHeight = 2560
largestNominalAppWidth = 2464
largestNominalAppHeight = 2560
logicalHeight = 2560
logicalWidth = 1440
所以经对比两种情况,状态栏高度值statusBarHeight计算公式可为:
statusBarHeight = logicalHeight-logicalHeight== largestNominalAppHeight? largestNominalAppWidth: largestNominalAppHeight;
@Override
protected int getDialogHeight()
{
Window window = getWindow();
if (window != null)
{
Display display = window.getWindowManager()
.getDefaultDisplay();
Point largestPoint = new Point();
Point realPoint = new Point();
display.getCurrentSizeRange(new Point(), largestPoint);
display.getRealSize(realPoint);
int height = realPoint.y == largestPoint.x ? largestPoint.y : largestPoint.x;
//此处旨在获取准确的多适配的去除状态栏的屏幕高度
//断点查看windowManager.getDefaultDisplay()
//这套流程依赖于"认为largestNominalAppWidth和largestNominalAppHeight字段相减的值为状态栏的高度"。
//可全面适配1.实体按键2.全面屏手势3.虚拟按键,可能仅适用于竖屏,横屏未经验证
//所以此处不需要主动计算获取状态栏高度
return height - ToolbarLayout.getToolbarHeight(getContext());
}
return super.getDialogHeight();
}
网友评论