兩分鐘理解Android中PX、DP、SP的區別

Donkor-發表於2017-08-29

轉載請標明出處:http://blog.csdn.net/donkor_/article/details/77680042

前言
眾所周知,Android廠商非常多,各種尺寸的android手機、平板層出不窮。導致了Android生態環境的碎片化現象越來越嚴重。Google公司為了解決解析度過多的問題,在Android的開發文件中定義了px、dp、sp,方便開發者適配不同解析度的Android裝置。對於初級程式設計師來說理解掌握適配的一些基礎知識是必須的。

▲ 基礎概念 :

px : 其實就是畫素單位,比如我們通常說的手機分辨列表800*400都是px的單位
sp : 同dp相似,還會根據使用者的字型大小偏好來縮放
dp : 虛擬畫素,在不同的畫素密度的裝置上會自動適配
dip: 同dp

▲ 舉個栗子 : px與dp
pixel,即畫素,1px代表螢幕上的一個物理的畫素點。但px單位不被建議使用。因為同樣畫素大小的圖片在不同手機顯示的實際大小可能不同。要用到px的情況是需要畫1畫素表格線或陰影線的時候,如果用其他單位畫則會顯得模糊。

要理解dp,首先要先引入dpi這個概念,dpi全稱是dots per inch,對角線每英寸的畫素點的個數,所以,它的計算公式如下:

dpi=height2+width2size
dpi = \dfrac{\sqrt{height^2 + width^2}}{size}

比如height和width即為長寬的畫素,平方和即為對角線的畫素個數,size即我們常說的5寸手機、4寸手機中的5和4,即對角線的長度。
所以,一樣是5寸的手機,解析度越高,dpi越高。解析度相同,螢幕對角線英寸數越小,dpi越高。

而dp也叫dip,是device independent pixels。裝置不依賴畫素的一個單位。在不同的畫素密度的裝置上會自動適配,比如:
在320x480解析度,畫素密度為160,1dp=1px
在480x800解析度,畫素密度為240,1dp=1.5px
計算公式:px = dp * (dpi/160)

我們做個簡單的Sample驗證一下,如下,一個佈局程式碼

    <Button
        android:layout_width="150px"
        android:layout_height="wrap_content"
        android:text="Test px" />
    <Button
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:text="Test dp" />

在480*800解析度中,3.7螢幕對角線英寸數的裝置效果圖如下

在480*800解析度中,5.1螢幕對角線英寸數的裝置效果圖如下

由此可以看出使用px作為單位的,在不同的裝置中會顯示不同的效果。使用dp作為單位的,會根據不同的裝置進行轉化,適配不同機型。所以建議在長度寬度的數值使用dp作為單位。

▲ 再舉個栗子 : dp與sp
既然我們在上面說了,dp可以自動適配裝置機型,那在字型裡是否也同樣可行?我們再做個簡單的Sample驗證一下,如下,一個佈局程式碼

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Test dp"
        android:textSize="20dp" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Test sp"
        android:textSize="20sp" />

在480*800解析度中,3.7螢幕對角線英寸數的裝置效果圖如下

在480*800解析度中,3.7螢幕對角線英寸數的裝置下,我們修改手機系統字型大小,得到效果圖如下

由此可以看出使用sp作為字型大小單位,會隨著系統的字型大小改變,而dp作為單位則不會。所以建議在字型大小的數值要使用sp作為單位

▲ 擴充
提供一個工具類:dp與px值轉換

public class DensityUtil {

    /**
     * 根據手機的解析度從 dp 的單位 轉成為 px(畫素)
     */
    public static int dp2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    /**
     * 根據手機的解析度從 px(畫素) 的單位 轉成為 dp
     */
    public static int px2dp(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }
}

About me
Email :donkor@yeah.net
Android開發交流QQ群 : 537891203
Android開發交流群

相關文章