## 像素
Android支持的像素單位常見的主要有下面三種:
* (1)px
它是手機屏幕上可顯示的最小單位,與物理設備的顯示屏有關。
一般來說,同樣尺寸的屏幕看起來越清晰,像素的密度越高,以px計量的分辨率也越大。
* (2)dp/dip
它與物理設備無關,只與屏幕的尺寸有關。
一般來說,同樣尺寸的屏幕以dp計量的分辨率是一樣的,無論這個手機是哪個廠家生產的,dp大小都一樣。
**密度無關像素** - **基于屏幕物理密度的抽象單位**。**這些單位相對于 160 dpi(每英寸點數)屏幕確立,在該屏幕上 1dp 大致等于 1px。在更高密度的屏幕上運行時,用于繪制 1dp 的像素數量會根據屏幕 dpi 按照適當的系數增加**。同樣,在更低密度的屏幕上,用于繪制 1dp 的像素數量會相應減少。**dp 對像素的比率會隨著屏幕密度的變化而變化,但不一定成正比。要使布局中的視圖尺寸根據不同的屏幕密度正確調整大小,一種簡單的解決辦法就是使用 dp 單位**(而不是 px 單位)。換句話說,**它可在不同設備上提供一致的界面元素大小**。
* (3)sp
它的原理跟dp差不多,專門用于設置字體大小。系統設置菜單里面,設置普通字體時,同數值dp和sp的文字看起來一樣大;如果設置為大字體,用dp設置的文字沒有變化,用sp設置的文字就變大了。
**縮放無關像素** - 這和 dp 單位類似,但**它也會根據用戶的字體大小偏好設置進行縮放。建議您在指定字體大小時使用此單位,以便字體大小會根據屏幕密度和用戶偏好設置進行調整。**
除了以上主要的3種,還有以下幾個
* `pt`
**點** - 1/72 英寸,基于屏幕的物理尺寸,假設屏幕密度為 72dpi。
* `mm`
**毫米** - 基于屏幕的物理尺寸。
* `in`
**英寸** - 基于屏幕的物理尺寸。
dp和px之間的聯系取決于具體設備上的像素密度,像素密度就是DisplayMetrics里的density參數。當density=1.0時,表示一個dp值對應一個px值;當density=1.5時,表示兩個dp值對應3個px值;當density=2.0時,表示一個dp值對應兩個px值。具體的轉換函數如下
```
// 根據手機的分辨率從 dp 的單位 轉成為 px(像素)
public static int dip2px(Context context, float dpValue) {
// 獲取當前手機的像素密度
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f); // 四舍五入取整
}
// 根據手機的分辨率從 px(像素) 的單位 轉成為 dp
public static int px2dip(Context context, float pxValue) {
// 獲取當前手機的像素密度
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f); // 四舍五入取整
}
```
在XML布局文件中,為了讓不同設備屏幕擁有統一的顯示效果,除了sp用于設置文字大小外,其余要用尺寸大小的地方都用dp。在代碼中情況又有所不同,Android用于設置大小的函數都以px為單位。無論是LayoutParams里的width和height,還是setMargins和setPadding,參數單位都是px,要想在代碼中使用dp設置布局大小或間距,得先把dp值轉換成px值。代碼示例如下:
```
// 將10dp的尺寸大小轉換為對應的px數值
int dip_10 = Utils.dip2px(this, 10L);
// 從布局文件中獲取名叫tv_padding的文本視圖
TextView tv_padding = findViewById(R.id.tv_padding);
// 設置該文本視圖的內部文字與控件四周的間隔大小
tv_padding.setPadding(dip_10, dip_10, dip_10, dip_10);
```
### 文件位置:
`res/values/*filename*.xml`
該文件名可以任意設置。`<dimen>`元素的`name`將用作資源 ID。
### 資源引用:
在 Java 中:`R.dimen.*dimension_name*`
在 XML 中:`@[*package*:]dimen/*dimension_name*`
### 語法:
~~~
? ? <?xml version="1.0" encoding="utf-8"?>
? ? <resources>
? ? ? ? <dimen
? ? ? ? ? ? name="dimension_name"
? ? ? ? ? ? >dimension</dimen>
? ? </resources>
~~~
### 元素:
* `<resources>`
**必需**。該元素必須是根節點。
沒有屬性。
* `<dimen>`
定義一個尺寸,由浮點數后跟度量單位(dp、sp、pt、px、mm、in)表示,如上所述。
屬性:
`name`
字符串。尺寸的名稱。該名稱將用作資源 ID。
### 示例:
保存在`res/values/dimens.xml`的 XML 文件:
~~~
? ? <?xml version="1.0" encoding="utf-8"?>
? ? <resources>
? ? ? ? <dimen name="textview_height">25dp</dimen>
? ? ? ? <dimen name="textview_width">150dp</dimen>
? ? ? ? <dimen name="ball_radius">30dp</dimen>
? ? ? ? <dimen name="font_size">16sp</dimen>
? ? </resources>
~~~
以下代碼會檢索出尺寸
~~~
? ? Resources res = getResources();
? ? float fontSize = res.getDimension(R.dimen.font_size);
~~~
以下布局 XML 會將尺寸應用到屬性:
~~~
? ? <TextView
? ? ? ? android:layout_height="@dimen/textview_height"
? ? ? ? android:layout_width="@dimen/textview_width"
? ? ? ? android:textSize="@dimen/font_size"/>
~~~