Android开发经验谈Android开发

px 、dp(dip) 和 sp 的相互换算(Android环境

2017-08-31  本文已影响166人  书柜里的松鼠

首先来看下这几个单位的具体含义:

官方文档是这样的:

dp
Density-independent Pixels - An abstract unit that is based on the physical density of the screen. These units are relative to a 160 dpi (dots per inch) screen, on which 1dp is roughly equal to 1px. When running on a higher density screen, the number of pixels used to draw 1dp is scaled up by a factor appropriate for the screen's dpi. Likewise, when on a lower density screen, the number of pixels used for 1dp is scaled down. The ratio of dp-to-pixel will change with the screen density, but not necessarily in direct proportion. Using dp units (instead of px units) is a simple solution to making the view dimensions in your layout resize properly for different screen densities. In other words, it provides consistency for the real-world sizes of your UI elements across different devices.
sp
Scale-independent Pixels - This is like the dp unit, but it is also scaled by the user's font size preference. It is recommend you use this unit when specifying font sizes, so they will be adjusted for both the screen density and the user's preference.
pt
Points - 1/72 of an inch based on the physical size of the screen, assuming a 72dpi density screen.
px
Pixels - Corresponds to actual pixels on the screen. This unit of measure is not recommended because the actual representation can vary across devices; each devices may have a different number of pixels per inch and may have more or fewer total pixels available on the screen.

歌词大意是说:
1.px 这个应该很熟悉了,就是屏幕上的实际像素。平时说的pc机屏幕的分辨率什么就是像素。
2.pt 屏幕的物理尺寸,相当于 1/72 英寸,研究过打印机的同学会比较熟悉。
3.sp 字体大小相关,指定字体大小时使用 sp ,就会根据屏幕密度调节文字的像素已尽量保证在不同屏幕密度下字体大小的一致。
4.dp(dip) 与密度无关的像素单位(或者说相关?),总之由于不同屏幕密度的设备上,一个像素点的物理大小是不一致的,同样100px大小的图标在不同设备上看上去大小不同,而使用dp的话就会根据屏幕密度进行缩放,已尽量保证原件显示尺寸的一致。

在实际场景中我们经常需要对这些单位进行换算来判断大小。

比如根据文本数量进行收缩或展开啦,比如对应不同的设备进行界面的排版啦……
转换公式很简单:

/**
     * 将px值转换为dip或dp值
     * @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 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 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 spValue
     * @return
     */
    public static int sp2px(Context context, float spValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (spValue * fontScale + 0.5f);
    }

需要注意的是这个+0.5f。
+0.5f前面算出来的其实就是实际值。然而,实际使用中我们一般用int就够了。(比如px不可能给你有显示半个像素的是吧。)又然而, (int)进行转化后其实就是吧小数点后的给抹掉了。比如0.1和0.9被(int)都是0。为了稍稍精确那么一点点,就加上0.5f进行四舍五入就完事了。

上一篇下一篇

猜你喜欢

热点阅读