DisplayMetrics信息获取:
//Display屏幕显示的详细信息
Display display = getWindowManager().getDefaultDisplay();
//从Display获取DisplayMetrics信息
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
PS:上面获取的DisplayMetrics只可读,第二种获取DisplayMetrics的方式:
context.getResources().getDisplayMetrics()
可修改里面的参数参考
以下为两个屏幕的DisplayMetrics
信息:
注意:上图4c的
xdpi
和ydpi
略有差值,后面会说到
-
widthPixels
:屏幕宽度 -
heightPixels
:屏幕高度 -
densityDpi
:屏幕密度,每英寸的像素数 -
density
:密度比值,和densityDpi
相关,其实就是densityDpi/160
得出来的值(160密度就是谷歌定的一个密度标准),不同手机dp换算px就是通过该值。 -
scaledDensity
:同density
,用于文字缩放的计算,也就是sp -
xDpi
:水平方向的真实密度 -
yDpi
:垂直方向的真是密度
densityDpi和density关系:
上面已经说了,density
就是densityDpi
除以标准密度160的出来的一个比值(参考上图),主要用于常用dp的计算,比如小米4c控件宽设为360dp的话,换算成像素就是1080px就是全屏了。
densityDpi和xDpi、yDpi的关系:
xDpi
和yDpi
是屏幕真实的屏幕密度,如上面小米mix2获取是403.411,而小米宣传的mix2屏幕密度就是403ppi,densityDpi
大概是厂家设定的一个值(确实没搞清这个值怎么得来的),咱们做界面适配基本也只会使用densityDpi
,xDpi
和yDpi
的使用后面会提。
下面放一个屏幕密度的简单的计算:
注意:上面配图获取的宽高信息是可用区域的信息,小米mix2的高其实是2160px,因为底部有虚拟导航栏,占掉一部分可用只有2030,屏幕详细信息可以通过
Display类
获取,下面有mix2的详细屏幕信息
关于Typevalue的计算 :
public static float applyDimension(int unit, float value,
DisplayMetrics metrics){
switch (unit) {
case COMPLEX_UNIT_PX:
return value;
case COMPLEX_UNIT_DIP:
return value * metrics.density;
case COMPLEX_UNIT_SP:
return value * metrics.scaledDensity;
case COMPLEX_UNIT_PT:
return value * metrics.xdpi * (1.0f/72);
case COMPLEX_UNIT_IN:
return value * metrics.xdpi;
case COMPLEX_UNIT_MM:
return value * metrics.xdpi * (1.0f/25.4f);
}
return 0;
}
dp的换算通过 metrics.density
,文字sp的换算通过metrics.scaledDensity
,而我们不常用的单位:pt磅,in英寸,mm毫米,都采用了xdpi
来计算,大概是因为这几个单位都是物理尺寸吧,比如in英寸的算法,就是value*xdpi
简单粗暴好理解。
PS:对于一块屏幕来说横向竖向的屏幕密度应该是一样的,因为其实就是一块玻璃嘛,屏幕密度都是均匀的,也就是说
xdpi
和ydpi
应该是一样的,最上面看到mix2的是一样的,小米4c居然略有不同,大概是小米4c屏幕略渣吧
关于粗暴适配的核心计算方法:原文
是一种百分比适配的方式,采用了冷门的pt作为单位 :
参考上文pt的原始计算方法 简写为如下:
value*xdpi/72
举例:假如设计稿宽度200,控件宽40,手机屏幕宽度1000像素
修改xdpi的值为:屏幕真实宽度÷设计稿宽度×72
xdpi = 1000/200*72
这样控件宽度算出来的结果就是:200像素百分20宽
value* (1000/200*72) /72 //括号内为xdpi的值
切记:
dp转像素:乘以density
像素转dp:除以density