• Android源码——TypedValue源码解析


    继承结构

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

    public class TypedValue {
    }
    
    • 1
    • 2

    常量

    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;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    整数

    开头数字作为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;
    
    • 1
    • 2
    • 3
    • 4

    常用类型

    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;
    
    • 1
    • 2
    • 3

    颜色

    将#开头的数字作为颜色、#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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    单位

    偏移量、掩码、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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    小数点

    小数点偏移量、小数点掩码、小数点第在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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    尾数偏移量、尾数掩码

    public static final int COMPLEX_MANTISSA_SHIFT = 8;
    public static final int COMPLEX_MANTISSA_MASK = 0xffffff;
    
    • 1
    • 2
    private static final float MANTISSA_MULT =1.0f / (1<
    • 1
    • 2
    • 3
    • 4
    • 5

    密度

    默认、无密度(不缩放)

    public static final int DENSITY_DEFAULT = 0;
    public static final int DENSITY_NONE = 0xffff;
    
    • 1
    • 2

    实际值

    public int type;
    public CharSequence string;
    public int data;
    public int assetCookie;
    public int resourceId;
    public int changingConfigurations = -1;
    public int density;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    方法

    转为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_RADIX_SHIFT) & TypedValue.COMPLEX_RADIX_MASK];
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    转为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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    转为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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    转为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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    set方法

    public void setTo(TypedValue other){
        type = other.type;
        string = other.string;
        data = other.data;
        assetCookie = other.assetCookie;
        resourceId = other.resourceId;
        density = other.density;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    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 : "").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();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    Mybatis-多表联查
    Ubuntu系统操作指南——命令行挂载U盘
    SpringBoot集成EasyExcel快速人们
    Python网络爬虫-re正则匹配数据
    安全运营 (历史漏洞修复)
    CentOS安装指定版本的Docker(包括卸载)
    Go语言中向[]byte数组中增加一个元素
    微信小程序云开发教程——墨刀原型工具入门(添加交互事件)
    [AI]大模型稳定角色扮演形成“自我认知”
    Hadoop大数据应用:HDFS 集群节点扩容
  • 原文地址:https://blog.csdn.net/qq_35258036/article/details/126890894