Android系统中的dp和px的转换

android系统中DP和SP的转化:
1.首先分析TypedValue.java

可以调用以下代码获得dp的值

TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20,getResources().getDisplayMetrics());

public static float applyDimension(int unit, float value,DisplayMetrics metrics)
    {
      switch (unit) {
            case COMPLEX_UNIT_PX:
            return value;
            case COMPLEX_UNIT_DIP:
            return value * metrics.density;
            case COMPLEX_UNIT_SP:
            return value * metrics.scaledDensity;
            case COMPLEX_UNIT_PT:
            return value * metrics.xdpi * (1.0f/72);
            case COMPLEX_UNIT_IN:
            return value * metrics.xdpi;
            case COMPLEX_UNIT_MM:
            return value * metrics.xdpi * (1.0f/25.4f);
        }
            return 0;
    }

 

2.接着分析Resource.java
在Resoucrce中会调用 mMetrics.setToDefaults();设置DisplayMetrics的density的值

 1  public Resources(AssetManager assets, DisplayMetrics metrics, Configuration config,
 2             CompatibilityInfo compatInfo, IBinder token) {
 3         mAssets = assets;
 4         mMetrics.setToDefaults();
 5         if (compatInfo != null) {
 6             mCompatibilityInfo = compatInfo;
 7         }
 8         mToken = new WeakReference<IBinder>(token);
 9         updateConfiguration(config, metrics);
10         assets.ensureStringBlocks();
11     }
12 
13  public void setToDefaults() {
14         widthPixels = 0;
15         heightPixels = 0;
16         density =  DENSITY_DEVICE / (float) DENSITY_DEFAULT;
17         densityDpi =  DENSITY_DEVICE;
18         scaledDensity = density;
19         xdpi = DENSITY_DEVICE;
20         ydpi = DENSITY_DEVICE;
21         noncompatWidthPixels = widthPixels;
22         noncompatHeightPixels = heightPixels;
23         noncompatDensity = density;
24         noncompatDensityDpi = densityDpi;
25         noncompatScaledDensity = scaledDensity;
26         noncompatXdpi = xdpi;
27         noncompatYdpi = ydpi;
28     }
29 
30  DENSITY_DEFAULT默认值为160,在系统中可以更改这个值
31   public static int DENSITY_DEVICE = getDeviceDensity();
32 
33   private static int getDeviceDensity() {
34     
35         return SystemProperties.getInt("qemu.sf.lcd_density",
36                 SystemProperties.getInt("ro.sf.lcd_density", DENSITY_DEFAULT));
37     }
38 
39 
40 
41 DENSITY_DEVICE是通过计算屏幕分辨率得出的,计算方式如下:

 

ro.sf.lcd_density的属性值:

-------------------------------
对于分辨路为720*1280 5.5寸:

ro.sf.lcd_density = 320
320/160 = 2
计算方式:720*1280 5.5寸 1280*1280+720*720 = 1648.6047/5.5 = 267.0190(取320)

--------------------------------------------------------------------
对于分辨路为1080*1920 5.5寸::

ro.sf.lcd_density = 320
480/160 = 3:
计算方式:1080*1920 5.5寸 2202.90707/5.5 = 400.5285(取480)

 

系统会将计算出的DPI转化成(120 160 240 320 480)

 

 

 


4.

通过以上分析可知

TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20,
getResources().getDisplayMetrics());
=20*getProp("ro.sf.lcd_density")/DENSITY_DEFAULT
= 20*getProp("ro.sf.lcd_density")/160

 

5在实际编程中,我们常用的dp和px转化代码是:区别就在于将float转化成了int,仅此而已

 /** 
     * 根据手机的分辨率从 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);  
    }  

 

你可能感兴趣的:(Android系统中的dp和px的转换)