你的位置:首页 > 操作系统

[操作系统]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);   }