dp、sp、px的关系和换算

来源:互联网 发布:mysql日期排序 编辑:程序博客网 时间:2024/04/29 01:12

做android开发的人都知道,在切图上跟UI设计师讨论dp/sp跟px的关系时都是很心累的。

一、dp、sp与px的定义

dp:英文全程为Density independent Pixels,设备无关像素,早期被叫做dip。
sp: 英文全程为Scale independent Pixel,缩放无关像素。
px: 英文全程为pixel,像素。

二、dp、sp与px的区别

讲这三者区别之前,首先应该说明什么是分辨率和像素密度。
分辨率:显示分辨率(屏幕分辨率)是屏幕图像的精密度,是指显示器所能显示的像素有多少。由
于屏幕上的点、线和面都是由像素组成的,显示器可显示的像素越多,画面就越精细,同样的屏幕
区域内能显示的信息也越多,所以分辨率是个非常重要的性能指标之一。可以把整个图像想象成是
一个大型的棋盘,而分辨率的表示方式就是所有经线和纬线交叉点的数目。显示分辨率一定的情况
下,显示屏越小图像越清晰,反之,显示屏大小固定时,显示分辨率越高图像越清晰。(摘自百度百科)
像素密度:英文全程为Dots Per Inch,每英寸所能显示的像素点即为像素密度,单位px/in。由于
通常我们提到的设备屏幕大小其实说的就是设备对角线的长度,所以通过厂商提供的分辨再结合勾
股定理即可算出像素密度。
px:在Android中不常用,因为一张100px*100px的图片在相同屏幕尺寸但分辨率不同的设备上显示的
大小是不一致的。通俗的讲就是在相同屏幕尺寸下,相同大小的图片在越大的分辨率下显示的越小。
dp:在Android中除了设置字体之外,需要明确指定尺寸的时候都是采用dp作为单位,因为在Android
系统中可以根据设备信息将dp转化为适合当前屏幕的px,从而达到适配的效果。
sp:在Android中主要用来设置字体,由于Android系统支持用户自定义字体大小(可以打开设备的设
置进入里面找字体大小一栏进行自定义),字体如果选择标准(普通/正常),那么1sp=1dp的。使用它
的原因跟使用dp的原因一致。

三、dp与px及sp与px的换算

这里提供两种换算方式,供你们参考。
第一种方式如下:

import android.content.Context;import android.util.TypedValue;public class DisplayNativeUtils {    /**     * dp转px     *     * @param context     * @return     */    public static int dp2px(Context context, float dpVal) {        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,                dpVal, context.getResources().getDisplayMetrics());    }    /**     * sp转px     *     * @param context     * @return     */    public static int sp2px(Context context, float spVal) {        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,                spVal, context.getResources().getDisplayMetrics());    }    /**     * px转dp     *     * @param context     * @param pxVal     * @return     */    public static float px2dp(Context context, float pxVal) {        final float scale = context.getResources().getDisplayMetrics().density;        return (pxVal / scale);    }    /**     * px转sp     *     * @param pxVal     * @return     */    public static float px2sp(Context context, float pxVal) {        return (pxVal / context.getResources().getDisplayMetrics().scaledDensity);    }}

第二种方法如下所示:

import android.content.Context;/** * 避免丢失精度所以都加上了0.5f */public class DisplayUtils {    /**     * 将px值转换为dip或dp值,保证尺寸大小不变     * @param context     * @param pxValue     * @return     */    public static int px2dip(Context context, float pxValue){        final float scale = context.getResources().getDisplayMetrics().density;        return (int) (pxValue / scale + 0.5f);    }    /**     * 将dip或dp值转换为px值,保证尺寸不变     * @param context     * @param dipValue     * @return     */    public static int dip2px(Context context, float dipValue) {        final float scale = context.getResources().getDisplayMetrics().density;        return (int) (dipValue * scale + 0.5f);    }    /**     * 将px值转换为sp值,保证文字大小不变     * @param context     * @param pxValue     * @return     */    public static int px2sp(Context context, float pxValue) {        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;        return (int) (pxValue / fontScale + 0.5f);    }    /**     * 将sp值转换为px值,保证文字大小不变     * @param context     * @param spValue     * @return     */    public static int sp2px(Context context, float spValue) {        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;        return (int) (spValue * fontScale + 0.5f);    }}

两种方法实质都是一样的,使用哪一种方法都可以。

源码地址:
https://github.com/Duckdan/dpAndspAndpx