详解Android应用中屏幕尺寸的获取及dp和px值的转换

时间:2021-12-06 23:40:12

获取屏幕尺寸

通过windowmanager获取

?
1
2
3
4
5
6
7
displaymetrics dm = new displaymetrics();
 
getwindowmanager().getdefaultdisplay().getmetrics(dm);
 
//其中display = getwindowmanager().getdefaultdisplay() 获得了一个defaultdisplay对象; 然后 display.getmetrics(dm) 把屏幕尺寸信息赋值给displaymetrics dm
 
//注意:windowmanager有时候需要通过context。getsystemservice获取:windowmanager wm = (windowmanager) context.getsystemservice(context.window_service);

displaymetrics和display的关系。;

display指代显示区域这个对象,它可能是真实的物理屏幕,也可能仅指应用程序的显示区域,比如在非全屏activity里,系统因为有状态栏,因此显示区域要比物理屏幕要小。displaymetrics里封装了显示区域的各种属性值。查看源码发现,在displaymetrics对各个属性值的注释都说明为真实的物理尺寸。而且也发现display.getmetrics(dm)这一函数基本在应用在获取真实屏幕尺寸的时候。记住这一点即好。

注:构造函数displaymetrics不需要传递任何参数;调用getwindowmanager()之后,会取得现有activity的handle。然后,diplay将取得的宽高维度存放于displaymetrics对象中,而取得的宽高维度是以像素为单位(pixel),“像素”所指的是“绝对像素”而非“相对像素”。

通过displaymetrics对象dm可以获得如下信息

?
1
2
3
4
5
6
7
8
9
10
11
width = dm.widthpixels;
 
height = dm.heightpixels;
 
xdpi = dm.xdpi;
 
ydpi = dm.ydpi;
 
density = dm.densitydpi;
 
fdensity = dm.density;

 

将dp和px转化成对应的px数值的实例:

?
1
2
3
4
5
int padding =4
 
padding = (int) typedvalue.applydimension(typedvalue.complex_unit_dip, 4,
 
context.getresources().getdisplaymetrics());

解释:
padding的单位是:dip, padding的大小是:4

虽然是4dip,但是,不是最终padding的真实单位。

他是通过计算以后,4dp和密度系数相乘得到的一个值,实际上计算出来的padding单位是像素,也就是它的宽度。在不同dpi的屏幕上,这个值是不一样的。

即:将dp转化为px,返回的是一个dp对应的px数值。

如果这里是complex_unix_sp,就是讲sp转化为dp。

单位间的转换就用这个方法,可以将其封装成一个工具方法。

进一步理解:
applydimension方法是将4像素转换为6dp(480x800)、4dp(320x800)、3dp(240x320), 所以返回的值对应不同的分辨率(通过getdisplaymetrics就得到了)就是6、4、3

源代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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;
 
}