--张学友《心如刀割》很好听
先说几个术语:
Screen size(屏幕尺寸):
指的是手机实际的物理尺寸,比如常用的2.8英寸,3.2英寸,3.5英寸,3.7英寸
摩托罗拉milestone手机是3.7英寸
Aspect Ratio(宽高比率):
指的是实际的物理尺寸宽高比率,分为long和nolong
Milestone是16:9,属于long
Resolution(分辨率)
和电脑的分辨率概念一样,指手机屏幕纵、横方向像素个数
Milestone是854*480
DPI(dot per inch) - <图像每英寸长度内的像素点数>
每英寸像素数,如120dpi,160dpi等,假设QVGA(320*240)分辨率的屏幕物理尺寸是(2英寸*1.5英寸),dpi=160
可以反映屏幕的清晰度,用于缩放UI的
Density(密度)
屏幕里像素值浓度,resolution/Screen size可以反映出手机密度,
Density-independent pixel (dip)
指的是逻辑密度计算单位,dip和具体像素值的对应公式是dip/pixel=dpi值/160,也就是px = dp * (dpi / 160)
手机像素密度(density)实际上是以单位英寸160个像素作为参考标准,主要密度有0.75,1,1.5和2,当密度为2时就表示1英寸有320个像素,Android中通过代码可以获取到屏幕的像素值和密度,根据这些值就可以反向算出屏幕的物理尺寸
屏幕尺寸=屏幕对角线的像素值/(密度*160)= [(长的平方+宽的平方)开根号] / (密度*160)
实践过程:
由于Android设备中获取的密度density本身是个约等于的数值,比如计算出密度的准确值density=1.575,实际在代码中读到的density=1.5, 需要实现一个简单的计算屏幕尺寸的应用在不同设备上验证物理尺寸准确程度,具体代码如下:
DisplayMetrics metric = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metric);
int width = metric.widthPixels; // 屏幕宽度(像素)
int height = metric.heightPixels; // 屏幕高度(像素)
float density = metric.density; // 屏幕密度(0.75 / 1.0 / 1.5)
int densityDpi = metric.densityDpi; // 屏幕密度DPI(120 / 160 / 240)
double diagonalPixels = Math.sqrt(Math.pow(width, 2)+Math.pow(height, 2)) ;
double screenSize = diagonalPixels/(160*density) ;
有可能上面的计算屏幕的尺寸不是太准确
这段描述和代码解释了通过 Android 提供的 DisplayMetrics
类获取设备屏幕尺寸的方法,并讨论了其中的准确性问题。总体来说,这段描述和代码是正确的,但有一些关键点需要更详细的分析。
1. 关于屏幕密度 (density
)
-
density
:确实如描述所说,density
是一个相对值,表示基于标准 160 dpi 的比例因子。例如,density=2
表示设备的像素密度是标准 160 dpi 的 2 倍,即 320 dpi。 -
densityDpi
:是屏幕的实际像素密度,表示每英寸的像素数。例如,densityDpi=240
表示屏幕的像素密度为 240 dpi。
2. 计算屏幕尺寸的公式
公式:
屏幕尺寸=宽度2+高度2density×160\text{屏幕尺寸} = \frac{\sqrt{\text{宽度}^2 + \text{高度}^2}}{\text{density} \times 160}屏幕尺寸=density×160宽度2+高度2
这个公式从屏幕的对角线像素数出发,将其除以 density * 160
以得到屏幕的物理尺寸(通常以英寸为单位)。这个公式背后的逻辑是:
-
density * 160
表示屏幕的像素密度(即每英寸有多少个像素),其中160
是标准密度 DPI 的基准。 -
宽度2+高度2\sqrt{\text{宽度}^2 + \text{高度}^2}宽度2+高度2 计算的是屏幕对角线的像素数。
3. 代码的实际准确性问题
如描述中所提到的,实际测量的 density
是一个近似值,而不是一个精确值。对于一些设备,实际的 density
可能会在代码中显示为 1.5
,而实际值可能更接近 1.575
。这种误差可能导致计算出的屏幕物理尺寸略有偏差。
误差来源:
- 近似值误差:
density
是一个近似值,可能会导致计算误差。虽然误差通常较小,但在某些设备上可能会显著影响屏幕尺寸的精确性。 - 屏幕密度的取整:Android 设备通常将
density
四舍五入到最接近的常用值(如 0.75、1.0、1.5、2.0),这使得计算出的物理尺寸有时不够精确。
4. 改进建议
为了提高准确性,可以考虑以下方法:
-
使用
xdpi
和ydpi
:而不是使用近似的density
值,你可以使用xdpi
和ydpi
来计算屏幕的物理尺寸。xdpi
和ydpi
是分别表示水平方向和垂直方向的实际像素密度,它们通常比density
更精确。改进后的公式:
屏幕尺寸=宽度2+高度2sqrt(xdpi2+ydpi2)\text{屏幕尺寸} = \frac{\sqrt{\text{宽度}^2 + \text{高度}^2}}{\text{sqrt}(\text{xdpi}^2 + \text{ydpi}^2)}屏幕尺寸=sqrt(xdpi2+ydpi2)宽度2+高度2
5. 总结
- 你描述的方法和代码是有效的,并且在大多数情况下可以近似计算屏幕尺寸。
- 由于
density
可能是一个近似值,这种计算方法可能存在一定误差。如果需要更准确的结果,建议使用xdpi
和ydpi
,它们能够提供更精确的像素密度值,从而提高计算的准确性。
为了提高屏幕物理尺寸计算的准确性,我们可以使用屏幕的实际像素密度(xdpi
和 ydpi
)来代替 density
。这样可以减少由于近似值导致的误差,从而更加准确地计算出设备的屏幕尺寸。下面是改进后的代码以及详细解释。
改进后的计算方法
所需参数:
- 屏幕分辨率:屏幕的宽度像素数(
widthPixels
)和高度像素数(heightPixels
)。 - 实际像素密度:水平方向和垂直方向的像素密度,分别是
xdpi
和ydpi
。
计算公式:
-
计算屏幕宽度和高度的英寸值:
2.通过勾股定理计算屏幕的对角线长度(即物理尺寸):
改进后的代码示例
import android.content.Context;
import android.util.DisplayMetrics;public class ScreenSizeUtil {public static double getScreenSizeInInches(Context context) {// 获取DisplayMetrics实例DisplayMetrics dm = context.getResources().getDisplayMetrics();// 获取屏幕的宽度和高度(以像素为单位)int widthPixels = dm.widthPixels;int heightPixels = dm.heightPixels;// 获取水平方向和垂直方向的像素密度(以每英寸像素数为单位)float xdpi = dm.xdpi;float ydpi = dm.ydpi;// 计算屏幕宽度和高度的英寸值double widthInInches = widthPixels / xdpi;double heightInInches = heightPixels / ydpi;// 使用勾股定理计算屏幕的物理尺寸(对角线长度)return Math.sqrt(Math.pow(widthInInches, 2) + Math.pow(heightInInches, 2));}
}
解释
-
获取屏幕分辨率:
widthPixels
和heightPixels
是屏幕的实际分辨率,表示屏幕的宽度和高度的像素数。
-
获取实际像素密度:
xdpi
和ydpi
表示水平方向和垂直方向的像素密度,分别表示每英寸的像素数。
-
计算屏幕宽度和高度的英寸值:
- 宽度和高度的英寸值是通过将像素数除以对应方向的像素密度得到的。
-
计算屏幕的物理尺寸:
- 通过勾股定理计算屏幕的对角线长度,得到实际的屏幕尺寸(通常以英寸为单位)。
改进后的优点
- 准确性更高:使用
xdpi
和ydpi
而不是近似的density
值,减少了由于density
的四舍五入或近似值引起的误差。 - 适应性更强:这段代码可以在各种 Android 设备上更加准确地计算屏幕尺寸,适用于需要精确测量屏幕尺寸的场景。
通过这种方式,计算出的屏幕物理尺寸更加接近设备的实际尺寸,适用于需要精确显示效果的应用场景。