Android源码——TypedValue源码解析

继承结构

TypedValue存储了动态类型数据的值,也是自定义属性中format的可选项

public class TypedValue {
}

常量

Android特有

空数据、引用数据(如@string)、Theme中的attrs数据、尺寸(如dp)、分数(百分比)

public static final int TYPE_NULL = 0x00;
public static final int TYPE_REFERENCE = 0x01;
public static final int TYPE_ATTRIBUTE = 0x02;
public static final int TYPE_DIMENSION = 0x05;
public static final int TYPE_FRACTION = 0x06;

整数

开头数字作为int、十进制、十六进制、末尾数字作为int

public static final int TYPE_FIRST_INT = 0x10;
public static final int TYPE_INT_DEC = 0x10;
public static final int TYPE_INT_HEX = 0x11;
public static final int TYPE_LAST_INT = 0x1f;

常用类型

string、float、boolean

public static final int TYPE_STRING = 0x03;
public static final int TYPE_FLOAT = 0x04;
public static final int TYPE_INT_BOOLEAN = 0x12;

颜色

将#开头的数字作为颜色、#aarrggbb、#rrggbb、#argb、#rgb,末尾int作为颜色

public static final int TYPE_FIRST_COLOR_INT = 0x1c;
public static final int TYPE_INT_COLOR_ARGB8 = 0x1c;
public static final int TYPE_INT_COLOR_RGB8 = 0x1d;
public static final int TYPE_INT_COLOR_ARGB4 = 0x1e;
public static final int TYPE_INT_COLOR_RGB4 = 0x1f;
public static final int TYPE_LAST_COLOR_INT = 0x1f;

单位

偏移量、掩码、px、dip、sp、pt、in、mm、百分比、占父控件百分比

public static final int COMPLEX_UNIT_SHIFT = 0;
public static final int COMPLEX_UNIT_MASK = 0xf;
public static final int COMPLEX_UNIT_PX = 0;
public static final int COMPLEX_UNIT_DIP = 1;
public static final int COMPLEX_UNIT_SP = 2;
public static final int COMPLEX_UNIT_PT = 3;
public static final int COMPLEX_UNIT_IN = 4;
public static final int COMPLEX_UNIT_MM = 5;
public static final int COMPLEX_UNIT_FRACTION = 0;
public static final int COMPLEX_UNIT_FRACTION_PARENT = 1;

小数点

小数点偏移量、小数点掩码、小数点第在24/8/16/0位

public static final int COMPLEX_RADIX_SHIFT = 4;
public static final int COMPLEX_RADIX_MASK = 0x3;
public static final int COMPLEX_RADIX_23p0 = 0;
public static final int COMPLEX_RADIX_16p7 = 1;
public static final int COMPLEX_RADIX_8p15 = 2;
public static final int COMPLEX_RADIX_0p23 = 3;

尾数偏移量、尾数掩码

public static final int COMPLEX_MANTISSA_SHIFT = 8;
public static final int COMPLEX_MANTISSA_MASK = 0xffffff;
private static final float MANTISSA_MULT =1.0f / (1<<TypedValue.COMPLEX_MANTISSA_SHIFT);
private static final float[] RADIX_MULTS = new float[] {
    1.0f*MANTISSA_MULT, 1.0f/(1<<7)*MANTISSA_MULT,
    1.0f/(1<<15)*MANTISSA_MULT, 1.0f/(1<<23)*MANTISSA_MULT
};

密度

默认、无密度(不缩放)

public static final int DENSITY_DEFAULT = 0;
public static final int DENSITY_NONE = 0xffff;

实际值

public int type;
public CharSequence string;
public int data;
public int assetCookie;
public int resourceId;
public int changingConfigurations = -1;
public int density;

方法

转为Float

  • 将int类型的data转为float,只有当Type=TYPE_FLOAT
  • 将传入的int转为float
public final float getFloat() {
    return Float.intBitsToFloat(data);
}

public static float complexToFloat(int complex){
    return (complex&(TypedValue.COMPLEX_MANTISSA_MASK <<TypedValue.COMPLEX_MANTISSA_SHIFT)) * RADIX_MULTS[(complex>>TypedValue.COMPLEX_RADIX_SHIFT) & TypedValue.COMPLEX_RADIX_MASK];
}

转为Dimension

将存有Dimension的数据

  • 转为float,单位不变
  • 转为int,单位为px
  • 转为int,单位为ps
  • 转为float,加上打印
public static float complexToDimension(int data, DisplayMetrics metrics){
    return applyDimension((data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK,complexToFloat(data),metrics);
}

public static int complexToDimensionPixelOffset(int data,DisplayMetrics metrics){
    return (int)applyDimension((data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK,complexToFloat(data),metrics);
}

public static int complexToDimensionPixelSize(int data,DisplayMetrics metrics){
    final float value = complexToFloat(data);
    final float f = applyDimension( (data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK,value,metrics);
    final int res = (int)(f+0.5f);
    if (res != 0) return res;
    if (value == 0) return 0;
    if (value > 0) return 1;
    return -1;
}

public static float complexToDimensionNoisy(int data, DisplayMetrics metrics){
    float res = complexToDimension(data, metrics);
    System.out.println(
        "Dimension (0x" + ((data>>TypedValue.COMPLEX_MANTISSA_SHIFT)
                           & TypedValue.COMPLEX_MANTISSA_MASK)
        + "*" + (RADIX_MULTS[(data>>TypedValue.COMPLEX_RADIX_SHIFT)
                            & TypedValue.COMPLEX_RADIX_MASK] / MANTISSA_MULT)
        + ")" + DIMENSION_UNIT_STRS[(data>>COMPLEX_UNIT_SHIFT)
                            & COMPLEX_UNIT_MASK]
        + " = " + res);
    return res;
}


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

public float getDimension(DisplayMetrics metrics){
    return complexToDimension(data, metrics);
}

转为Fraction

public static float complexToFraction(int data, float base, float pbase){
    switch ((data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK) {
    	case COMPLEX_UNIT_FRACTION:
        	return complexToFloat(data) * base;
    	case COMPLEX_UNIT_FRACTION_PARENT:
        	return complexToFloat(data) * pbase;
    }
    return 0;
}

public float getFraction(float base, float pbase){
    return complexToFraction(data, base, pbase);
}

转为String

private static final String[] DIMENSION_UNIT_STRS = new String[] {
    "px", "dip", "sp", "pt", "in", "mm"
};
private static final String[] FRACTION_UNIT_STRS = new String[] {
    "%", "%p"
};
public final CharSequence coerceToString(){
    int t = type;
    if (t == TYPE_STRING) {
        return string;
    }
    return coerceToString(t, data);
}

public static final String coerceToString(int type, int data){
    switch (type) {
    case TYPE_NULL:
        return null;
    case TYPE_REFERENCE:
        return "@" + data;
    case TYPE_ATTRIBUTE:
        return "?" + data;
    case TYPE_FLOAT:
        return Float.toString(Float.intBitsToFloat(data));
    case TYPE_DIMENSION:
        return Float.toString(complexToFloat(data)) + DIMENSION_UNIT_STRS[
            (data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK];
    case TYPE_FRACTION:
        return Float.toString(complexToFloat(data)*100) + FRACTION_UNIT_STRS[
            (data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK];
    case TYPE_INT_HEX:
        return "0x" + Integer.toHexString(data);
    case TYPE_INT_BOOLEAN:
        return data != 0 ? "true" : "false";
    }
    if (type >= TYPE_FIRST_COLOR_INT && type <= TYPE_LAST_COLOR_INT) {
        return "#" + Integer.toHexString(data);
    } else if (type >= TYPE_FIRST_INT && type <= TYPE_LAST_INT) {
        return Integer.toString(data);
    }
    return null;
}

set方法

public void setTo(TypedValue other){
    type = other.type;
    string = other.string;
    data = other.data;
    assetCookie = other.assetCookie;
    resourceId = other.resourceId;
    density = other.density;
}

toString方法

public String toString(){
    StringBuilder sb = new StringBuilder();
    sb.append("TypedValue{t=0x").append(Integer.toHexString(type));
    sb.append("/d=0x").append(Integer.toHexString(data));
    if (type == TYPE_STRING) {
        sb.append(" \"").append(string != null ? string : "<null>").append("\"");
    }
    if (assetCookie != 0) {
        sb.append(" a=").append(assetCookie);
    }
    if (resourceId != 0) {
        sb.append(" r=0x").append(Integer.toHexString(resourceId));
    }
    sb.append("}");
    return sb.toString();
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值