Android中的常用尺寸單位(dp、sp)快速入門教程

NO IMAGE

常見尺寸單位

Android開發中的常用尺寸單位有如下幾種:

dp (dip)
px
pt
inch
sp

算不知道確切含義,相信對於以上這幾種尺寸單位大家也都比較臉熟,這裡先讓我們重新認識一下它們:

dp (dip): 即裝置無關畫素(device independent pixels),這種尺寸單位在不同裝置上的物理大小相同。
px:即畫素(pixel),這個不用多說。
pt:通常用來作為字型的尺寸單位,1 pt相當於1/72英寸。
inch:英寸,1 英寸約等於2.54釐米,主要用來描述手機螢幕的大小。
sp:大部分人只知道它通常用作字型的尺寸單位,實際大小還與具體裝置上的使用者設定有關。(如果你對”sp”的瞭解停留於此,那麼看完這篇文章後你會更透徹的理解它^ _ ^)

在上面幾種常見的尺寸單位,dp和sp可以看做是虛擬尺寸。其中dp是與裝置無關的虛擬畫素單位,開發者為UI控制元件指定以dp為單位的大小後,在不同螢幕密度的Android裝置上便能夠具有相同的物理尺寸。dp的出現讓開發者無需關注螢幕密度、物理畫素之間的換算關係。sp則與dp相似,但它主要用作字型的尺寸單位,與dp的區別是:Android系統支援使用者設定字型大小,因而sp的實際大小還會根據使用者設定在原基礎上進行縮放。

下面來詳細介紹dp與sp這兩種尺寸單位。

尺寸單位詳解之dp

dp的全稱是device independent pixels,在具有不同螢幕密度的裝置上,1 dp的物理大小是相同的。那麼,什麼是螢幕密度呢?

螢幕密度

手機的螢幕密度通常指的是手機螢幕的dpi(dots per inch),也就是每英寸的畫素數。對於Android手機來說,常見的dpi有如下幾種:

ldpi:對應的dpi範圍為0 ~ 120,也就是說每英寸有0到120個畫素點的螢幕的螢幕密度都屬於ldpi
mdpi:dpi範圍為120 ~ 160
hdpi:dpi範圍為160 ~ 240
xhdpi:dpi範圍為240~320
xxhdpi:dpi範圍為320~480

在實際開發中,通常以dpi值120、160、240、320、480分別指代ldpi、mdpi、hdpi、xhdpi、xxhdpi。通常螢幕密度越大的手機顯示的影象會越細膩。可以通過如下程式碼獲取當前Android裝置的螢幕密度:


private void getDpi() {
DisplayMetrics dm = getResources().getDisplayMetrics();
Log.i("TAG", "density = "   dm.density);
Log.i("TAG", "densityDpi = "   dm.densityDpi);
}

若我們在一臺螢幕密度為320dpi的Android手機上執行以上程式碼,會得到如下輸出:


density = 2
densityDpi = 320

上面輸出中的densityDpi就是Android手機螢幕的dpi值,那麼density是什麼呢?實際上它代表的是當前螢幕的dpi值與基準dpi值的比值,這個基準dpi值為160。
現在我們已經理解了dpi,接下來讓我們揭開dp的神祕面紗。

dp

上面我們提到了選擇dpi值160作為基準螢幕密度,這個基準螢幕密度人為建立起了dp與px間的關係:在dpi為160的Android裝置上,1 dp = 1px。假設x為某UI控制元件以px為單位的大小,y為同一UI控制元件以dp為單位的大小,densityDpi表示螢幕密度,則x與y的關係為:x = y * densityDpi / 160。

介紹完了dp,接下來讓我們探究一下sp這個尺寸單位的真面目。

尺寸單位詳解之sp

在介紹sp之前,我們先來一起看下TypedValue類中包含的一個使用者將dp、sp等單位轉換為px的靜態方法:


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;
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;
}

若要將dp轉換為px,會執行如下程式碼:


return value * metrics.density;

density我們在前面介紹過,指的是當前dpi與基準dpi(160)的比值。density的計算方式就是當前螢幕的dpi除以160。也就是說,在螢幕的dpi為120、160、320、480時,density的值分別為0.75、1、2、3。
若要將sp轉換為px,則會執行如下程式碼:


return value * metrics.scaledDensity;

可以看到,sp轉換為px的計算公式與dp轉換為px時相似,那麼scaledDensity是什麼呢?實際上,scaledDensity不同於density,scaledDensity是可以動態改變的,當使用者改變了Android裝置的字型縮放比例時,scaledDensity的值就會發生變化。scaledDensity的計算公式為:scaledDensity = density * fontScale。其中fontScale代表使用者設定的Android裝置字型縮放比例,預設為1。也就是說,當使用者沒有改變Android裝置的字型縮放比例時,sp、dp與px的換算是相同的。

多解析度之殤

市面上存在著的各種不同解析度的Android裝置為廣大Android開發者挖了眾多的坑,比如:

需要為不同解析度的Android裝置單獨維護一套dimens檔案;
通常UI設計師只會針對某種特定解析度的裝置為我們標註UI控制元件的畫素大小,相信不少小夥伴都受夠了手動換算不同解析度裝置上UI控制元件畫素大小的痛苦;
通常我們需要為每種解析度的Android裝置維護一個drawable資料夾以獲得比較好的圖片顯示效果,這會導致apk檔案尺寸的臃腫;而且若某個drawable資料夾下的圖片需要修改,那麼就需要替換其他所有drawable資料夾中對應的圖片。如果不小心漏掉了某個drawable資料夾下的圖片,則會導致該圖片在某些解析度的手機上失真。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對指令碼之家的支援。

您可能感興趣的文章:

android計算pad或手機的解析度/畫素/密度/螢幕尺寸/DPI值的方法android app icon 圖示大小尺寸詳解Android應用中螢幕尺寸的獲取及dp和px值的轉換Android程式設計實現螢幕自適應方向尺寸與解析度的方法Android的單位以及螢幕解析度詳解Android 圖片切換器(dp、sp、px) 的單位轉換器Android中dip、dp、sp、pt和px的區別詳解解析android中的dip,dp,px,sp和螢幕密度