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);  
    }  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM