Android原生系统API自带dp、px、sp单位转换

Android系统中自带的Api中可以使用TypedValue进行单位转换

1,调用系统api转换单位

// 获得转换后的px值
float pxDimension = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 16,context.getResources().getDisplayMetrics());

2,分析TypedValue.applyDimension搞了什么事情?

// 在TypedValue类中
/**
 * px、dp、sp、pt、in、mm单位转换
 * @param unit  转换类型
 * @param value 转换值(float)
 * @param metrics 当前设备显示密度
 * @return 转换单位后的值
 */
public static float applyDimension(int unit, float value, DisplayMetrics metrics) {
    switch (unit) {
        case COMPLEX_UNIT_PX: // 转换为px(像素)值
            return value;
        case COMPLEX_UNIT_DIP: // 转换为dp(密度)值
            return value * metrics.density;
        case COMPLEX_UNIT_SP: // 转换为sp(与刻度无关的像素)值
            return value * metrics.scaledDensity;
        case COMPLEX_UNIT_PT: // 转换为pt(磅)值
            return value * metrics.xdpi * (1.0f / 72);
        case COMPLEX_UNIT_IN: // 转换为in(英寸)值
            return value * metrics.xdpi;
        case COMPLEX_UNIT_MM: // 转换为mm(毫米)值
            return value * metrics.xdpi * (1.0f / 25.4f);
    }
    return 0;
}

3,分析context.getResources().getDisplayMetrics()搞了什么事情

// 在Resource类中
final DisplayMetrics mMetrics = new DisplayMetrics();

// 构造方法,初始化了mMetrics
public Resources(AssetManager assets, DisplayMetrics metrics, Configuration config,
         CompatibilityInfo compatInfo) {
     mAssets = assets;
     mMetrics.setToDefaults();
     if (compatInfo != null) {
         mCompatibilityInfo = compatInfo;
     }
     updateConfiguration(config, metrics);
     assets.ensureStringBlocks();
}

// 获取密度值的方法
public DisplayMetrics getDisplayMetrics() {
        if (DEBUG_CONFIG) Slog.v(TAG, "Returning DisplayMetrics: " + mMetrics.widthPixels
                + "x" + mMetrics.heightPixels + " " + mMetrics.density);
        return mMetrics;
    }
}

// 在DisplayMetrics类中
public void setToDefaults() {
        widthPixels = 0;
        heightPixels = 0;
        density =  DENSITY_DEVICE / (float) DENSITY_DEFAULT;
        densityDpi =  DENSITY_DEVICE; // 获取密度值
        scaledDensity = density;
        xdpi = DENSITY_DEVICE;
        ydpi = DENSITY_DEVICE;
        noncompatWidthPixels = widthPixels;
        noncompatHeightPixels = heightPixels;
        noncompatDensity = density;
        noncompatDensityDpi = densityDpi;
        noncompatScaledDensity = scaledDensity;
        noncompatXdpi = xdpi;
        noncompatYdpi = ydpi;
    }

// 获取密度值    
public static int DENSITY_DEVICE = getDeviceDensity();
private static int getDeviceDensity() {
    return SystemProperties.getInt("qemu.sf.lcd_density", // 获取当前系统的密度值
            SystemProperties.getInt("ro.sf.lcd_density", DENSITY_DEFAULT)); // 没有,则取默认值
}

// 获取密度缺省值:160
public static final int DENSITY_DEFAULT = DENSITY_MEDIUM;
public static final int DENSITY_MEDIUM = 160;

当然在实际编程中,我们一般都把单位转换写成工具类,通过工具类来调用:

/**
 * 根据手机分辨率从DP转成PX
 * @param context
 * @param dpValue
 * @return
 */
public static int dip2px(Context context, float dpValue) {
    float scale = context.getResources().getDisplayMetrics().density;
    return (int) (dpValue * scale + 0.5f);
}

/**
 * 将sp值转换为px值,保证文字大小不变
 * @param spValue
 * @return
 */
public static int sp2px(Context context, float spValue) {
    final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
    return (int) (spValue * fontScale + 0.5f);
}

/**
 * 根据手机的分辨率PX(像素)转成DP
 * @param context
 * @param pxValue
 * @return
 */
public static int px2dip(Context context, float pxValue) {
    float scale = context.getResources().getDisplayMetrics().density;
    return (int) (pxValue / scale + 0.5f);
}

/**
 * 将px值转换为sp值,保证文字大小不变
 * @param pxValue
 * @return
 */

public static int px2sp(Context context, float pxValue) {
    final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
    return (int) (pxValue / fontScale + 0.5f);
}

你可能感兴趣的:(android实用技巧)