android 分辨率適配與dip(dp)的使用

若是想在不一樣型號手機對同一個應用作適配,若是你在xml中所有使用dp沒有使用px,那麼適配上依然頗有可能出問題!

無數人存在誤區,認爲本身使用的都是dp,爲何在手機A上面和手機B上面看上去比例不同,爲何在A手機上顯示正好而手機B上卻顯示到屏幕外面

每次解釋的都很累,因此寫此blog

首先先明確幾個概念
density值表示每英寸有多少個顯示點(*)

dip/dp: device independent pixels(設備獨立像素)
注意:dip與屏幕密度有關,屏幕密度與硬件有關,硬件設置不正確,有可能致使dip不能正常顯示。在屏幕密度爲160的顯示屏上,1dip=1px

下面是一些分辨率信息

html

名稱 分辨率 屏幕密度
QVGA 320*240 120
WQVGA400 400*240 120
WQVGA432 432*240 120
HVGA 640*480 160
WSVGA 1024*600 160
WXGA800 1280*800 160
WVGA800 800*480 240
WVGA854 854*480 240
WXGA720 1280*720 320

下面沒有特殊說明的話,屏幕的寬度都指其像素數
咱們在手機A上面放了一張圖片,120px寬,手機屏幕240px寬,也就是說圖片的寬度佔了整個屏幕的一半
若是把應用安裝在手機B上,B的寬度=320px,那麼咱們但願圖片寬度爲多少呢?若是你們但願按着比例縮放,那圖片寬度應該是160px,佔屏幕寬度的50%

若是咱們在xml中使用的單位爲dp,下面看看如何保持這個比例:
px = (density/160)dp(density這裏是(*)的意思)
咱們把所期待的比例記爲rate,baseDensity=160,屏幕的寬度(像素數)爲x,屏幕密度爲density
那麼rate=((density/baseDensity)*dp)/x;
這裏baseDensity是已知的=160,dp也是已知的,由於是你寫的嘛。
未知的是density屏幕密度和屏幕寬度x

rate能夠寫爲:
rate=(dp/baseDensity)*(density/x);
如今狀況就比較明朗了,rate=K(常數)*(density/x);
若是想保持rate不變,那麼須要保證density/x保持比例

給數學很差的同窗多解釋兩句
想保持rate的話,必需要手機A的屏幕密度/屏幕寬度=手機B的屏幕密度/屏幕寬度
或者說手機A的屏幕密度/手機B的屏幕密度=手機A的屏幕寬度/手機B的屏幕寬度

一樣,若是你要保持縱向也保持等比縮放,那麼也一樣須要保持比例。
只有這樣,你的應用才能看上去是等比縮放的。
使用dp保持比例只和這些有關,和你屏幕大小半點關係都沒有。

還有另外一種方式來保持比例:就是直接使用比例方式定義組件大小
可是頗有侷限性,只有LinearLayout中可使用android:layout_weight屬性

其實很容易理解,給你們舉個例子
不少人以爲,若是項目中所有使用dp,那麼就能夠完美移植。
咱們的一個移植項目,任務是把應用從A(分辨率爲WXGA720=1280*720)移植到B(分辨率WVGA800=800*480)
其中A的密度=320,B的密度爲240

咱們如今來看看A橫向有多少個dp
A dp數=720/(320/160)=360
B dp數=480/(240/160)=320

手機A橫向有360個dp,若是你的圖片佔用360個dp,B去哪找你多出來的40dp呢!必然它會顯示在屏幕外面阿!


ps:下面是一點相關內容
下面是函數void android.util.DisplayMetrics.setToDefaults()
public void setToDefaults() {
    widthPixels = 0;
    heightPixels = 0;
    density = DENSITY_DEVICE / (float) DENSITY_DEFAULT;
    densityDpi = DENSITY_DEVICE;
    scaledDensity = density;
    xdpi = DENSITY_DEVICE;
    ydpi = DENSITY_DEVICE;
    noncompatWidthPixels = 0;
    noncompatHeightPixels = 0;
}

其中density變量註釋以下

density變量註釋 寫道java

float android.util.DisplayMetrics.density
The logical density of the display.
This is a scaling factor for the Density Independent Pixel unit, where one DIP is one pixel on an approximately 160 dpi screen (for example a 240x320, 1.5"x2" screen), providing the baseline of the system's display.
Thus on a 160dpi screen this density value will be 1; on a 120 dpi screen it would be .75; etc.
This value does not exactly follow the real screen size (as given by xdpi and ydpi, but rather is used to scale the size of the overall UI in steps based on gross changes in the display dpi.
For example, a 240x320 screen will have a density of 1 even if its width is 1.8", 1.3", etc.
However, if the screen resolution is increased to 320x480 but the screen size remained 1.5"x2" then the density would be increased (probably to 1.5).
See Also:
DENSITY_DEFAULT
android.util.DisplayMetrics.density
邏輯密度的顯示。
這是一個比例因子的密度獨立像素單元,其中一個是一個像素上蘸一個大約160 dpi屏幕(例如240 x320,1.5 " x2 "屏幕),提供基線系統的顯示。
所以在一個160 dpi屏幕這密度值是1;在一個120 dpi屏幕會。75;等等。
這個值並不徹底遵循真正的屏幕大小(由xdpi和ydpi,而是用來規模大小的總體UI在步驟基於總改變顯示dpi。
例如,一個240 x320屏幕將會有一個密度的1即便它的寬度爲1.8」,1.3」,等等。
然而,若是屏幕分辨率是增長到320 x480,可是屏幕大小保持1.5 " x2」而後密度會增長(多是1.5)。
參見:
密度默認

轉自:http://www.eoeandroid.com/thread-193122-1-1.htmlandroid

相關文章
相關標籤/搜索