android顯示的一些單位density dpi dp(dip) sp px及分辨率的概念,對於這些單位,還在一頭霧水?
Come On,就是這篇文章了。當然看懂了本篇,可以再看下這篇:點擊打開鏈接 ,瞭解android對於屏幕大小的規定及加載layout的參數影響。
這裏爲了防止每個概念都是動態的,我們把px固定,即出廠了的屏幕的像素點不會變了。(屏幕像素點大小:同樣的5寸屏幕,垃圾屏的像素點大,顯示模糊;好屏的像素點小,顯示精細)。
後面分析的前提條件都是同一塊手機屏幕,px是一個定值。
放大後,下面的一個個點,就是像素。
一、概念:
-
ScreenSize(屏幕尺寸)
這個是指屏幕對角線的長度,後面計算的單位都是/inc,這個inc就是以屏幕尺寸爲基準(作爲除數)的來的。(盜圖不可恥)
-
Resolution(分辨率)
是指屏幕的垂直和水平方向的像素數量,如果分辨率是 1920*1080 ,那就是垂直方向有 1920 個像素,水平方向有 1080 個像素。 -
Dpi(像素密度)
是指屏幕上每英寸(1英寸 = 2.54 釐米)距離中有多少個像素點。常見的120、160、240、320、480等。(dpi是dot per inch,每英寸多少點,ppi是 Pixel per inch,每英寸像素數,針對顯示器的設計時,dpi=ppi。ppi計算方法是長寬各自平方之和開方,除以對角線長度(單位英寸)。見下圖。)
-
Density(密度)
密度。常見取值1.5、1.0等 。和標準dpi的比例(標準dpi爲:160px/inc)。這個其實就是倍數:320dpi的density就是2.0)320/160),其餘density的取值,根據其dpi與標準dpi的比例值得到。 -
Dip / dp (設備獨立像素)
也可以叫做dp,長度單位,同一個單位在不同的設備上有不同的顯示效果,具體效果根設備的密度有關(注意:跟密度有關)。 -
Px (Pixel像素)
也稱爲圖像元素,是作爲圖像構成的基本單元。這裏簡單的認爲,一個屏幕出廠了,這個px就固定了。
概念有點蒙?沒關係,上圖(盜圖不可恥):
二、相互關係
從一部分的概念,基本就知道了dpi是有分辨率決定的,分辨率越高,dpi也就越大,沒有錯,是這樣的。
從上圖中可以看到主要的值:
屏幕尺寸:5inc、屏幕分辨率:1080x1920、dpi:440px/inc。dp放到後面在理解。
到此,基本就知道了,一塊屏幕出廠了,分辨率固定了,屏幕尺寸固定了,dpi也是固定的。
But,看到了問題:不同廠商的屏幕大小不一樣,分辨率不一樣,那不就有很多的density了嗎,很亂啊。
是的,so,google粑粑爲了解決這個問題, Android 中內置了幾個默認的 Dpi ,在特定的分辨率下自動調用,也可以手動在配置文件中修改,如下圖。
那麼問題來了,g粑粑固定了dpi,那和分辨率不就沒有直接換算的關係了嗎。是的,是的,是的,所以不小心就會出很多問題,比如cts問題,自定義圖片然後設置各種佈局的dp等等。
這些後面會講,這一部分就知道:實際上dpi是由分辨率計算的到的,dpi和分辨率是有關係的。But,google將其剝離開來了,手機中的dp,sp均以來dpi計算,包括dpi都和分辨率不在有毛線關係,只不過dpi的設置是參考分辨而選取設置的,不是精確計算的了。
三、分辨率固定,看下dpi、dp、sp、px的關係
先看一張圖:(分辨率720x1280,選的的density是320)
這張圖最上面是兩個320px的textview,正好鋪滿720px寬的屏幕。
下面一次是360dp和360sp的textview,也鋪滿了屏幕(後面會講sp--px及dp--px的關係)。
下面是一個.9圖片,最下面顯示的是當前手機的display的信息。
從上圖中看到320dp和320sp都充滿的720px的屏幕,也就是在dpi爲320的時候1dp=1sp=2px了(320/160=2,第一部分density概念介紹)。
dp和sp是根據dpi的變化而變化的值。看下google粑粑的換算:
/**
* Converts an unpacked complex data value holding a dimension to its final floating
* point value. The two parameters <var>unit</var> and <var>value</var>
* are as in {@link #TYPE_DIMENSION}.
*
* @param unit The unit to convert from.
* @param value The value to apply the unit to.
* @param metrics Current display metrics to use in the conversion --
* supplies display density and scaling information.
*
* @return The complex floating point value multiplied by the appropriate
* metrics depending on its unit.
*/
public static float applyDimension(int unit, float value,
DisplayMetrics metrics)
{
switch (unit) {
case COMPLEX_UNIT_PX:
return value;
case COMPLEX_UNIT_DIP:
return value * metrics.density;
case COMPLEX_UNIT_SP:
return value * metrics.scaledDensity;//A:這裏先忽略,scaledDensity默認和density是一樣的。
case COMPLEX_UNIT_PT:
return value * metrics.xdpi * (1.0f/72);
case COMPLEX_UNIT_IN:
return value * metrics.xdpi;
case COMPLEX_UNIT_MM:
return value * metrics.xdpi * (1.0f/25.4f);
}
return 0;
}
從上面code:px是直接返回大小的,其他的值,需要轉換爲px再返回。
dip也就是dp是當前的值,乘以density;sp需要乘以scaledDensity的到px。
A點解釋:sp的換算爲什麼是個sacaled的density呢?在“seeting--顯示--字體大小”中,可以修改字體大小,這個值就是scaledDensity,如果默認的話,就是density,其他的則會個density乘以一個係數的到這個scaledDensity。這也就是爲啥設置字體大小之改變文字大小的原因(文字(TextView)單位一般都是sp)。
到此,基本高清了dp、sp、px三者依賴dpi的換算關係了。
再看兩張圖,加深下印象:
第一張圖是dpi是80,可以看到360dp的只佔180個像素(當前dpi/標準dpi:80/160=0.5);
第二張圖是dpi爲160,標準dpi,360dp就佔了360個像素。
同時這兩張和dpi=320的那張比,也可以看到.9圖片不一樣大了,這是因爲我使用了統一張.9圖片,如果,希望不同的density下,圖片顯示一樣大,就需要畫不同的圖片分當不同的文件夾下。google粑粑源碼中res下面分了很多個文件夾就是這個作用。
所以,在自定義圖片,佈局中,要注意在不同density手機上,是可能存在問題的。當遇到顯示問題的時候,可以先check下自己自定義佈局中的單位是否存在問題。