## 像素
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"/>
~~~