Android的手机屏幕,不管时分辨率还是大小都是五花八门、千奇百怪的,这在一定程度上造成了绘图时的难度。要想在不同的屏幕上保持绘图的精准性,那么我们必须对这些屏幕都有充分的认识。


1.屏幕参数


        


  • 屏幕大小

        指屏幕对角线的长度,通常使用“寸”来度量,例如4.7寸手机、5.5寸手机等。


  • 分辨率

        分辨率是指手机屏幕的像素点个数,例如720*1280就是值屏幕的分辨率,指宽度右720个像素点,而搞有1280个像素点。


  • PPI

        每英寸像素(Pixels Per Inch)又称DPI(Dots Per Inch)。他们是由对角线的像素点除以屏幕的大小得到的,通常达到400PPI就已经是非常高的屏幕密度了。


2.系统屏幕密度


        每个厂商的Android手机具有不同的大小尺寸和像素密度的屏幕。Android系统如果要精确到每种DPI的屏幕,那基本是不可能的。因此,系统定义了几个标准的DPI值,作为手机的固定DPI,如表所示。


  密度  

ldpi

mdpi

hdpi

xhdpi

xxhdpi

  密度值  

120

160

240

320

480

  分辨率  

240*320

320*480

480*800

720*1280

1080*1920



3.独立像素密度dp


        正是由于各种屏幕密度的不同,导致同样像素大小的长度,在不同密度的屏幕上显示长度不同。因为相同长度的屏幕,高密度的屏幕包含更多的像素点。Android系统中视图mdpi即密度值为160的屏幕作为标准,在这个屏幕上1px = 1dp.其他屏幕则可以通过比例进行换算,例如同样是100dp的长度,在mdpi中为100px,在hdpi中为150px。我们也可以得出在各个密度值中的换算公式,在mdpi中1dp=1px,在hdpi中1dp=1.5px,在xhdpi中1dp=2px,在xxhdpi中1dp=3px。由此我们也可以得到各个分辨率直接的换算比例,即ldpi:mdpi:hdpi:xhdpi:xxhdpi=3:4:6:8:12。



4.单位换算


        在程序中,可以非常方便的对这些单位进行换算。下面的代码给出了一个转换的方法,我们可以把这些代码作为工具类保存到项目中。 



/**
 * dp、sp转为px的工具类
 * Created by 72312 on 2017/12/25.
 */

public class DisplayUtil {

    /**
     * 将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);
    }
}



        其中density就是前面所说的换算比例。这里使用的是公式换算方法进行转换。同时,系统也提供了TypedValue类帮助我们转换,代码如下所示。


protected int dp2px(int dp){
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                dp,getResources().getDisplayMetrics());
    }

    protected int sp2px(int sp){
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
                sp,getResources().getDisplayMetrics());
    }