1.屏幕密度是否可以修改?
2.屏幕密度与分辨率的关系?
3.px与dip之间的转换与屏幕密度的关系?
1.屏幕密度是否可以修改
Android中保存屏幕密度的系统变量为:ro.sf.lcd_density,
此变量可以在相应的mk文件中进行修改:
PRODUCT_PROPERTY_OVERRIDES := \ ro.sf.lcd_density=320 \
2.屏幕密度与分辨率的关系
先看一组分辨率与DPI(dot per inch ,每英寸像素数)的对应关系:
4:3
VGA 640*480 (Video Graphics Array)
QVGA 320*240 (Quarter VGA)
HVGA 480*320 (Half-size VGA)
SVGA 800*600 (Super VGA)
5:3
WVGA 800*480 (Wide VGA)
16:9
FWVGA 854*480 (Full Wide VGA)
HD 1920*1080 High Definition
QHD 960*540
720p 1280*720 标清
1080p 1920*1080 高清
分辨率对应DPI
"HVGA mdpi"
"WVGA hdpi "
"FWVGA hdpi "
"QHD hdpi "
"720P xhdpi"
"1080P xxhdpi
再看Android源码中的DPI与屏幕密度对应关系的定义:
public static final int DENSITY_LOW = 120; /** * Standard quantized DPI for medium-density screens. */ public static final int DENSITY_MEDIUM = 160; public static final int DENSITY_TV = 213; public static final int DENSITY_HIGH = 240; public static final int DENSITY_XHIGH = 320; public static final int DENSITY_XXHIGH = 480; public static final int DENSITY_XXXHIGH = 640; /** * The reference density used throughout the system. */
默认的density:
public static final int DENSITY_DEFAULT = DENSITY_MEDIUM; private static int getDeviceDensity() { // qemu.sf.lcd_density can be used to override ro.sf.lcd_density // when running in the emulator, allowing for dynamic configurations. // The reason for this is that ro.sf.lcd_density is write-once and is // set by the init process when it parses build.prop before anything else. return SystemProperties.getInt("qemu.sf.lcd_density", SystemProperties.getInt("ro.sf.lcd_density", DENSITY_DEFAULT)); }
前面说到ro.sf.lcd_density可以设置,那么在FWVGA屏的时候,是否可以设置成320呢,答案是可以的,
只是在显示效果上有很大的区别,同一分辨率的屏,lcd_density设置得越大,在屏幕上显示出来的
字和图片也就越大,具体的原因看第三个问题的分析。
3.px与dip之间的转换与屏幕密度的关系
先看转换的公式:dip值 =设备密度/160* px值
为验证此等式,做了一个测试:
<TextView android:id="@+id/testText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <Button android:id="@+id/button1" android:layout_width="100px" android:layout_height="100px" android:text="button_1" android:layout_below="@id/testText" /> <Button android:id="@+id/button2" android:layout_width="100dip" android:layout_height="100dip" android:text="button_2" android:layout_toRightOf="@id/button1" android:layout_alignTop="@id/button1" />
当density设置为:320时,效果图
从效果图上可以看出,当density为240时:dip值 =1.5* px值
当density为320时:dip值 =2 * px值
网上也有很多工具类,如
/** * 将dip或dp值转换为px值,保证尺寸大小不变 * * @param dipValue * @param scale(DisplayMetrics类中属性density) * @return */ public static int dip2px(float dipValue, float scale) { return (int) (dipValue * scale + 0.5f); }
上面的scale=getResources().getDisplayMetrics().density;
此处确实会引起很多的误解,density不是密度吗?这和上面的公式完全不对啊,
先看看源码中对此处的density的赋值:
density = DENSITY_DEVICE / (float) DENSITY_DEFAULT; densityDpi = DENSITY_DEVICE; scaledDensity = density;
其中:DENSITY_DEVICE = getDeviceDensity() //即设备密度
DENSITY_DEFAULT = DENSITY_MEDIUM //即为160
这样替换进去就和上面的一样了,后面加的0.5为了使变量不为零
获取设备的density的真正方法应该是:
getResources().getDisplayMetrics().densityDpi