android分辨率px跟dp,Android屏幕适配 px,dp,dpi及density的关系与深入理解
PX(pixel):
即傳統計算機語言中描述的像素,在Android則代表絕對像素。
之所以Android中不推薦使用這種單位,正是因為不同生產廠商,不同品牌,不同屏幕的設備,其分辨率亦不一。
舉例來說,我們現在將某個Button的width設為160px,則會出現如下情況:
在分辨率為“320寬”的設備里,該按鈕顯示占屏幕寬度一半;
在分辨率為“640寬”的設備里,該按鈕顯示占屏幕寬度的四分之一;
DPI(Dots Per Inch):
為了避免上面說到的使用px在屏幕適配中帶來的問題,Android引入了一個新的單位:dp/dpi。
而在理解“dp”之前,我們更有必要先了解一下另一個概念。正是:dpi。
也有人講dpi稱為“屏幕密度”。其含義則是:每英寸所打印的點數,既每一英寸的屏幕所包含的英寸數。
舉例來說,假設現在有一臺“寬2英寸,長3英寸”的設備,則:
當該設備分辨率為“320*480”,則dpi值為160。
當該設備分辨率為“640*960”,則dpi值為320。
而“dpi”值越高的設備,其屏幕顯示畫面的效果也就越精細。
使用場景:
正是因為dpi值其代表的特性,所以android項目的資源文件下存在以下目錄:
drawable-ldpi ? ?( 當dpi為120時,使用此目錄下的資源)
drawable-mdpi ? ?( 當dpi為160時,使用此目錄下的資源)
drawable-hdpi ? ?( 當dpi為240時,使用此目錄下的資源)
drawable-xhdpi ? ( 當dpi為320時,使用此目錄下的資源)
drawable-xxhdpi ?( 當dpi為480時,使用此目錄下的資源)
Android正是根據設備DPI值得不同,選擇清晰度不同的資源使用,完成屏幕的適配。
DP/DIP(device independent pixels):
與我們之前談到的絕對密度“px”對應,Android中引入的“dp”代表的則是“設備獨立像素”。
該單位是為支持WVGA、HVGA和QVGA而使用的,其不再依賴像素本身,而是和屏幕密度相關。
在Android當中規定:在屏幕密度為“160dpi”的情況下,則剛好“1dp = 1px”。
注:當屏幕密度為“320dpi”時,則“1dp = 2px”,以此類推.......
也正是因此,讓我們得以保證了:控件在不同密度的屏幕上顯示一致,既完成屏幕適配。
使用場景:
讓我們回到上面說到的使用px造成的控件顯示問題,此時我們將使用新的單位“dp”。于是:
在分辨率320*480(既dpi為160)的設備下,則160dp等價于160px,按鈕占屏幕寬的一半。
在分辨率640*960(既dpi為320)的設備下,則160dp等價于320px,按鈕依然占屏幕寬的一半。
Density:
就這個單詞本身直接翻譯的意思而言,其也代表“密度”。
但需要注意的是,在Android中,其實并非如此。
注意我們這里指的是,通過代碼“context.getResources().getDisplayMetrics().density”獲取的“density”值。
而通過該方法獲取到的該值,實際上是等價于“dpi / 160”的一個結果值。也就是說:
“getResources().getDisplayMetrics().density” = “getResources().getDisplayMetrics().densityDpi / 160”
看到這樣一個解析,聰明的人大概已經能預見什么了。我們似乎發現了某種關聯:
在Android里:“dpi = 160,則1dp = 1px”、“dpi = 320,則1dp = 2px”。以此類推。
到此你已經發現,dp,px與160之間存在著某種規律:“1dp = (dpi / 160)px”
換算一下,最終得到公式:?dp = density * px。
到了這里我們明白了,其實Android提供的該值,也就是為了讓我們在dp與px之間做轉換。
歸根結底,其目的還是為了幫助我們做屏幕適配。
使用場景:
雖然使用dp在xml文件中定義控件尺寸,能夠很好的幫助我們完成適配。
但很多時候,我們也會需要在Java代碼中動態的去設定控件的尺寸。
但由于在代碼中的尺寸設定,基本都被默認為了px單位。
所以這個時候就可以借助“density”來幫我們完成dp與px的轉換,從而完成適配。
這也是為什么,我們可以在網上查到類似的工具類代碼:
public static int dip2px(Context context, float dipValue){
final float scale = context.getResources().getDisplayMetrics().density;
return (int)(dipValue * scale + 0.5f);
}
public static int px2dip(Context context, float pxValue){
final float scale = context.getResources().getDisplayMetrics().density;
return (int)(pxValue / scale + 0.5f);
}注:不要奇怪,熟悉的Java的特性的你應該明白,“+0.5f”是為了避免在類型強制轉換中可能造成的精度丟失.
到了這里,我們總算小有收獲。最后,通過一段代碼,來驗證一下我們的總結和猜想:
DisplayMetrics metrices = getResources().getDisplayMetrics();
int dpi = metrices.densityDpi;
float density = metrices.density;
float width = metrices.widthPixels;
float height = metrices.heightPixels;
Log.i("dpi==>", dpi+"");
Log.i("density==>", density+"");
Log.i("width==>", width+"");
Log.i("height==>", height+"");
查看打印結果:
總結
以上是生活随笔為你收集整理的android分辨率px跟dp,Android屏幕适配 px,dp,dpi及density的关系与深入理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java数据库表不存在_如果Java生产
- 下一篇: php 输出中文的引号,如何将php英文