Android density與顯示效果總結
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設定為:240時,效果圖
當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