标签:
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); }
标签:
原文地址:http://www.cnblogs.com/jiadongfeng/p/4789892.html