当前位置: 代码迷 >> Android >> Android系统中的dp跟px的转换
  详细解决方案

Android系统中的dp跟px的转换

热度:79   发布时间:2016-04-27 23:04:43.0
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);      }  

 

  相关解决方案