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