前言: 眾所周知,Android廠商非常多,各種尺寸的android手機、平板層出不窮。導致了Android生態環境的碎片化現象越來越嚴重。Google公司為瞭解決解析度過多的問題,在Android的開發文檔中定義了px、dp、sp,方便開發者適配不同解析度的Android設備。對於初級程式員來說理 ...
前言:
眾所周知,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,對角線每英寸的像素點的個數,所以,它的計算公式如下:
比如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);
}
}