android 中sp、dp、px的详解

来源:互联网 发布:永琪因知画误会小燕子 编辑:程序博客网 时间:2024/05/21 17:33

转载请注明出自flowsky37的博客的博客,尊重他人辛苦劳动!

在说sp、sp、px之前先说下分辨率和像素之间的关系,可能有的哥们不太清楚。我们经常说手机的分辨率是1920*1080,或是其它的多少,那这个1080和1920到底指的是什么呢?说这个又得要先说像素,像素是组成图像最基本的单元要素。分辨率便是指在长和宽两个方向上个拥有的像素个数,一个像素有多大就主要取决于显示器的分辨率,相同面积不同分辨率的显示屏,其像素点的大小就不相同。

例如一个分辨率为640*480的显示屏,则表示在长的方向上有640个像素点,宽的方向上有480个像素点。总数就是640*480=307200(个像素),简称30万像素。所以单位面积上像素点越多即像素点越小,这图片就越清晰细腻。

还有一个屏幕像素密度的计算,大家都知道手机屏幕的尺寸指的是对角线的长度,一般都是英寸为单位。那么屏幕密度是怎么计算呢?下面看一个例子:就拿小米4的屏吧,它的分辨率是1920*1080。这两个说了分别对应是常和宽方向上的像素个数,根据勾股定理,就可以得出其对焦线的上的像素个约为2202.907,除以5就可以得到像素密度ppi为440.581。当然,小米肯定会四舍五入的宣称自己手机屏幕像素密度ppi为441。

回到正题,在android系统中,dp和dip是同一个东西,早期叫dip后来为了和sp统一,改成dp。英文名:devices independent pixes(设备独立像素)。

px:pixels(像素)。

sp:scaled pixes(放大像素),在android中用于字体的设置。当然字体也可以用dp设置,但官方推荐用sp。

dp:也就是dip,device independent pixels(设备独立像素)。不同设备显示的效果相同,与密度无关。规定如果屏幕密度为160时,dp、sp以及px之间的关系为:1px = 1sp = 1dp。如果拿px做单位的话,如果手机屏幕的尺寸不变,但是密度增大一倍的话,那px就得增大一倍。例如某手机密度为160,将一个控件的长度设为100px。如果手机的密度变为320,尺寸不变,还是设置空间的长度为100px,这时控件显示会缩短一半,因为像素点缩小了一倍。但是如果设置的单位为dp或者sp,就会根据手机屏幕的密度进行自动转换,不用自己去考虑屏幕的密度,永远是你设置的那个尺寸比例。

特别是在android中用canvas进行画图的时候,里面用的尺寸单位是px,如果不转换成dp的话,在不同的分辨率手机上显示的效果肯定是不一样的。下面给出一个dp与px,以及sp与px相互转换的工具类。

package com.bob.application.displeydensity;import android.content.Context;public class PixelsUtils {    private Context context;    public PixelsUtils(Context context) {        this.context = context;    }    /**     * @param pxValue 传入的px的值     *  px转换为sp     */    public int pxTosp(float pxValue){        final float scale = context.getResources().getDisplayMetrics().scaledDensity;        return (int)(pxValue/scale+0.5f);    }    /**     *     * @param spValue 传入的sp的值。     * sp转换为px     */    public int spTopx(float spValue){        final float scale = context.getResources().getDisplayMetrics().scaledDensity;        return (int)(spValue * scale + 0.5f);    }    /**     *     * @param pxValue   传入的像素值     *  px转换为dp     */    public int pxTodp(float pxValue){        final float scale = context.getResources().getDisplayMetrics().density;        return (int)(pxValue / scale + 0.5f);    }    /**     *     * @param dpValue 传入的dp的值     *  dp转换为px     */    public int dpTopx(float dpValue){        final float scale = context.getResources().getDisplayMetrics().density;        return (int)(dpValue * scale + 0.5f);    }}

一般情况下在任何一台手机打印scale的值是你会发现,context.getResources().getDisplayMetrics().density与context.getResources().getDisplayMetrics().scaledDensity 的值其实是一样。有人可能就要问了,那sp和dp到底有什么区别呢。其实大部分情况下他俩没什么区别,如果你手上有小米手机的话,你可以在设置里找到一个设置字体显示的选项,里面有小号、默认、中号及大号的选择。一般情况下,系统使用的是默认,当你将字体大小的选择改动了的话,再打印scale的值,你会发现上面两个方法的值不一样了,这时候就体现出了sp和dp的区别了。scale我们俗称为比例因子吧,此时的dp和sp的比例因子不一致了,那么你之前写好的布局就会有问题了,显示肯定是不成比例。
下面是三星A7手机默认时打印的情况:
三星A7
如果我在系统设置中将字体调整为更小一号时,结果为:
三星A7
看到变化了吧,如果我将系统字体调整比必默认的大时:
三星A7

我再将测试机换为红米1,默认时设置时:
红米1
很明显的看出A7比红米的分辨率高。
当我把字体调整为小一号时:
红米1
当字体调整为大一号时:
红米1

前面说过大部分情况下dp和sp没多大的区别,但是此时做了调整后,无论是红米还是三星都很明显的就看出了它们之间的区别。其实dp和sp的区别也主要体现这些方面。

有些哥们开发的时候可能会遇到自己写的布局在其它手机都好着,怎么在某台手机怎么显示就是不对,非常郁闷。这时候你就看下是不是字体用的不是默认的,从而导致了显示混乱。

上面是个人对dp、sp、px的一些理解,如果有不明白的,可以留言;如果某些地方有误,非常欢迎指出,谢谢!**

0 0