我们在自定义View的过程中,通常会让用户通过自定义属性值来控制View的显示效果。那么我们应该如何自定义属性和使用这些属性呢?
第一:我们需要在工程目录下res/values新建一个attr.xml文件,在该文件中定义我们自己的自定义的属性名称。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="myTextView">
        <attr name="mColor" format="color"/>
        <attr name="mBoolean" format="boolean"/>
        <attr name="mDimension" format="dimension"/>
        <attr name="mFloat" format="float"/>
        <attr name="mInteger" format="integer"/>
        <attr name="mString" format="string"/>
        <attr name="mEnum" format="enum"/>
        <attr name="mFlag">
            <flag name="one" value="1"/>
            <flag name="two" value="2"/>
        </attr>
        <attr name="mFraction" format="fraction"/>
        <attr name="mReference" format="reference"/>
    </declare-styleable>
</resources>

第二: 我们就可以在我们布局文件使用这些自定义属性了。

<com.lgy.typearray.MyTextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        lgy:mColor="@color/material_blue_grey_900"
        lgy:mBoolean="true"
        lgy:mDimension="@dimen/abc_action_bar_progress_bar_size"
        android:text="Hello World!" />

第三:我们此时就可以在我们自定义View的构造函数中获取我们在布局文件中设置的对应值。

public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) {
   super(context, attrs, defStyleAttr);
   mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
   mPaint.setColor(Color.RED);

   TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.myTextView);

   mPaint.setColor(typedArray.getColor(R.styleable.myTextView_mColor, Color.RED));

   boolean mBoolean = typedArray.getBoolean(R.styleable.myTextView_mBoolean, false);
   Log.i(TAG, "mBoolean:" + mBoolean);

   float mDimension = typedArray.getDimension(R.styleable.myTextView_mDimension, 14f);
   Log.i(TAG, "mDimension:" + mDimension);
   int mDimensionSize = typedArray.getDimensionPixelSize(R.styleable.myTextView_mDimension, 14);
   Log.i(TAG, "mDimensionSize:" + mDimensionSize);
   int mDimensionPixelOffset = typedArray.getDimensionPixelOffset(R.styleable.myTextView_mDimension,14);
   Log.i(TAG, "mDimensionPixelOffset:" + mDimensionPixelOffset);
   typedArray.recycle();
}

到此使用方法就介绍好了。

下面我想在介绍的就是我们在attr.xml中 format对应值。

1、color 代表颜色值。

在attr.xml中我们可以<attr name="mColor" format="color"/>,

在我们布局文件中我们可以lgy:mColor="@color/mytextView",

颜色mytextView是我们在定义<color name="mytextView">#5896ae</color>,

我们在代码中获取我们设置对应值

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.myTextView); 
 int mColor = typedArray.getColor(R.styleable.myTextView_mColor, Color.RED); 
 Log.i(TAG,"mColor:" + mColor); 
 typedArray.recycle();

运行代码结果图:

navigationItem 自定义_xml

2、boolean代表真假true false

在attr.xml中我们可以<attr name="mBoolean" format="boolean"/>,

在我们布局文件中我们可以lgy:mBoolean="true",

我们在代码中获取我们设置对应值

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.myTextView); 
 int mColor = typedArray.getColor(R.styleable.myTextView_mColor, Color.RED); 
 Log.i(TAG,"mColor:" + mColor); 
 boolean mBoolean = typedArray.getBoolean(R.styleable.myTextView_mBoolean, false); 
 Log.i(TAG, "mBoolean:" + mBoolean); 
 typedArray.recycle(); 

运行代码结果图:

navigationItem 自定义_TypeArray_02

3、float代表浮点数

在attr.xml中我们可以<attr name="mFloat" format="float"/>,

在我们布局文件中我们可以lgy:mFloat="5",

我们在代码中获取我们设置对应值

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.myTextView); 
 int mColor = typedArray.getColor(R.styleable.myTextView_mColor, Color.RED); 
 Log.i(TAG,"mColor:" + mColor); 
 boolean mBoolean = typedArray.getBoolean(R.styleable.myTextView_mBoolean, false); 
 Log.i(TAG, "mBoolean:" + mBoolean); 
 float mFloat = typedArray.getFloat(R.styleable.myTextView_mFloat,0.0f); 
 Log.i(TAG,"mFloat:" + mFloat); 
 typedArray.recycle();

运行代码结果图:

navigationItem 自定义_xml_03

4、integer 代表整形

在attr.xml中我们可以<attr name="mInteger" format="integer"/>,

在我们布局文件中我们可以lgy:mInteger="16",

我们在代码中获取我们设置对应值

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.myTextView); 
 int mColor = typedArray.getColor(R.styleable.myTextView_mColor, Color.RED); 
 Log.i(TAG,"mColor:" + mColor); 
 boolean mBoolean = typedArray.getBoolean(R.styleable.myTextView_mBoolean, false); 
 Log.i(TAG, "mBoolean:" + mBoolean); 
 float mFloat = typedArray.getFloat(R.styleable.myTextView_mFloat,0.0f); 
 Log.i(TAG,"mFloat:" + mFloat); 
 int mInteger = typedArray.getInteger(R.styleable.myTextView_mInteger,1); 
 Log.i(TAG,"mInteger:" + mInteger); 
 int mInt = typedArray.getInt(R.styleable.myTextView_mInteger,2); 
 Log.i(TAG,"mInt:" + mInt); 
 typedArray.recycle();

运行代码结果图:

navigationItem 自定义_navigationItem 自定义_04

5、string 代表字符串

在attr.xml中我们可以<attr name="mString" format="string"/>,

在我们布局文件中我们可以lgy:mString="自定义字符串",

我们在代码中获取我们设置对应值

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.myTextView); 
 int mColor = typedArray.getColor(R.styleable.myTextView_mColor, Color.RED); 
 Log.i(TAG,"mColor:" + mColor); 
 boolean mBoolean = typedArray.getBoolean(R.styleable.myTextView_mBoolean, false); 
 Log.i(TAG, "mBoolean:" + mBoolean); 
 float mFloat = typedArray.getFloat(R.styleable.myTextView_mFloat,0.0f); 
 Log.i(TAG,"mFloat:" + mFloat); 
 int mInteger = typedArray.getInteger(R.styleable.myTextView_mInteger,1); 
 Log.i(TAG,"mInteger:" + mInteger); 
 int mInt = typedArray.getInt(R.styleable.myTextView_mInteger,2); 
 Log.i(TAG,"mInt:" + mInt); 
 String mString = typedArray.getString(R.styleable.myTextView_mString); 
 Log.i(TAG,"mString:" + mString); 
 typedArray.recycle();

运行代码结果图:

navigationItem 自定义_TypeArray_05

6、enum 代表枚举类型

在attr.xml中我们可以:

<attr name="mEnum" format="enum"> 
 <enum name="five" value="5"/> 
 <enum name="six" value="6"/> 
 <enum name="seven" value="7"/> 
 </attr>

在我们布局文件中我们可以lgy:mEnum="six",

我们在代码中获取我们设置对应值

 TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.myTextView); 
 int mColor = typedArray.getColor(R.styleable.myTextView_mColor, Color.RED); 
 Log.i(TAG,"mColor:" + mColor); 
 boolean mBoolean = typedArray.getBoolean(R.styleable.myTextView_mBoolean, false); 
 Log.i(TAG, "mBoolean:" + mBoolean); 
 float mFloat = typedArray.getFloat(R.styleable.myTextView_mFloat,0.0f); 
 Log.i(TAG,"mFloat:" + mFloat); 
 int mInteger = typedArray.getInteger(R.styleable.myTextView_mInteger,1); 
 Log.i(TAG,"mInteger:" + mInteger); 
 int mInt = typedArray.getInt(R.styleable.myTextView_mInteger,2); 
 Log.i(TAG,"mInt:" + mInt); 
 String mString = typedArray.getString(R.styleable.myTextView_mString); 
 Log.i(TAG,"mString:" + mString); 
 int mEnum = typedArray.getInteger(R.styleable.myTextView_mEnum,5); 
 Log.i(TAG,"mEnum:" + mEnum); 
 int mEnumInt = typedArray.getInt(R.styleable.myTextView_mEnum,7); 
 Log.i(TAG,"mEnumInt:" + mEnumInt); 
 typedArray.recycle();

运行代码结果图:

navigationItem 自定义_布局文件_06

7、flag 代表自定义类型

在attr.xml中我们可以:

<attr name="mFlag"> 
 <flag name="one" value="1"/> 
 <flag name="two" value="2"/> 
 </attr>

在我们布局文件中我们可以lgy:mFlag="two",

我们在代码中获取我们设置对应值

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.myTextView); 
 int mColor = typedArray.getColor(R.styleable.myTextView_mColor, Color.RED); 
 Log.i(TAG,"mColor:" + mColor); 
 boolean mBoolean = typedArray.getBoolean(R.styleable.myTextView_mBoolean, false); 
 Log.i(TAG, "mBoolean:" + mBoolean); 
 float mFloat = typedArray.getFloat(R.styleable.myTextView_mFloat,0.0f); 
 Log.i(TAG,"mFloat:" + mFloat); 
 int mInteger = typedArray.getInteger(R.styleable.myTextView_mInteger,1); 
 Log.i(TAG,"mInteger:" + mInteger); 
 int mInt = typedArray.getInt(R.styleable.myTextView_mInteger,2); 
 Log.i(TAG,"mInt:" + mInt); 
 String mString = typedArray.getString(R.styleable.myTextView_mString); 
 Log.i(TAG,"mString:" + mString); 
 int mEnum = typedArray.getInteger(R.styleable.myTextView_mEnum,5); 
 Log.i(TAG,"mEnum:" + mEnum); 
 int mEnumInt = typedArray.getInt(R.styleable.myTextView_mEnum,7); 
 Log.i(TAG,"mEnumInt:" + mEnumInt); 
 int mFlag = typedArray.getInteger(R.styleable.myTextView_mFlag,1); 
 Log.i(TAG,"mFlag:" + mFlag); 
 int mFlagInt = typedArray.getInt(R.styleable.myTextView_mFlag,1); 
 Log.i(TAG,"mFlagInt:" + mFlagInt); 
 typedArray.recycle();

运行代码结果图:

navigationItem 自定义_自定义_07

8、reference 代表引用 (布局文件、资源文件等)

在attr.xml中我们可以<attr name="mReference" format="reference"/>

在我们布局文件中我们可以lgy:mReference="@android:layout/simple_list_item_1",

我们在代码中获取我们设置对应值

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.myTextView); 
 int mColor = typedArray.getColor(R.styleable.myTextView_mColor, Color.RED); 
 Log.i(TAG,"mColor:" + mColor); 
 boolean mBoolean = typedArray.getBoolean(R.styleable.myTextView_mBoolean, false); 
 Log.i(TAG, "mBoolean:" + mBoolean); 
 float mFloat = typedArray.getFloat(R.styleable.myTextView_mFloat,0.0f); 
 Log.i(TAG,"mFloat:" + mFloat); 
 int mInteger = typedArray.getInteger(R.styleable.myTextView_mInteger,1); 
 Log.i(TAG,"mInteger:" + mInteger); 
 int mInt = typedArray.getInt(R.styleable.myTextView_mInteger,2); 
 Log.i(TAG,"mInt:" + mInt); 
 String mString = typedArray.getString(R.styleable.myTextView_mString); 
 Log.i(TAG,"mString:" + mString); 
 int mEnum = typedArray.getInteger(R.styleable.myTextView_mEnum,5); 
 Log.i(TAG,"mEnum:" + mEnum); 
 int mEnumInt = typedArray.getInt(R.styleable.myTextView_mEnum,7); 
 Log.i(TAG,"mEnumInt:" + mEnumInt); 
 int mFlag = typedArray.getInteger(R.styleable.myTextView_mFlag,1); 
 Log.i(TAG,"mFlag:" + mFlag); 
 int mFlagInt = typedArray.getInt(R.styleable.myTextView_mFlag,1); 
 Log.i(TAG,"mFlagInt:" + mFlagInt); 
 int mReference = typedArray.getResourceId(R.styleable.myTextView_mReference,0); 
 Log.i(TAG,"mReference:" + mReference); 
 typedArray.recycle();

运行代码结果图:

navigationItem 自定义_自定义_08

9、fraction 代表百分数

在attr.xml中我们可以<attr name="mFraction" format="fraction"/>

在我们布局文件中我们可以lgy:mFractinotallow="30%",

我们在代码中获取我们设置对应值

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.myTextView); 
 int mColor = typedArray.getColor(R.styleable.myTextView_mColor, Color.RED); 
 Log.i(TAG,"mColor:" + mColor); 
 boolean mBoolean = typedArray.getBoolean(R.styleable.myTextView_mBoolean, false); 
 Log.i(TAG, "mBoolean:" + mBoolean); 
 float mFloat = typedArray.getFloat(R.styleable.myTextView_mFloat,0.0f); 
 Log.i(TAG,"mFloat:" + mFloat); 
 int mInteger = typedArray.getInteger(R.styleable.myTextView_mInteger,1); 
 Log.i(TAG,"mInteger:" + mInteger); 
 int mInt = typedArray.getInt(R.styleable.myTextView_mInteger,2); 
 Log.i(TAG,"mInt:" + mInt); 
 String mString = typedArray.getString(R.styleable.myTextView_mString); 
 Log.i(TAG,"mString:" + mString); 
 int mEnum = typedArray.getInteger(R.styleable.myTextView_mEnum,5); 
 Log.i(TAG,"mEnum:" + mEnum); 
 int mEnumInt = typedArray.getInt(R.styleable.myTextView_mEnum,7); 
 Log.i(TAG,"mEnumInt:" + mEnumInt); 
 int mFlag = typedArray.getInteger(R.styleable.myTextView_mFlag,1); 
 Log.i(TAG,"mFlag:" + mFlag); 
 int mFlagInt = typedArray.getInt(R.styleable.myTextView_mFlag,1); 
 Log.i(TAG,"mFlagInt:" + mFlagInt); 
 int mReference = typedArray.getResourceId(R.styleable.myTextView_mReference,0); 
 Log.i(TAG,"mReference:" + mReference); 
 float mFraction = typedArray.getFraction(R.styleable.myTextView_mFraction,2,4,0); 
 Log.i(TAG,"mFraction:" + mFraction); 
 typedArray.recycle();

运行代码结果图:

navigationItem 自定义_xml_09

**注意:**lgy:mFractinotallow=”30%”

navigationItem 自定义_navigationItem 自定义_10

**注意:**lgy:mFractinotallow=”30%p”

注意到我们设置lgy:mFractinotallow=”“值不同得到的结果不一样,那么我们在调用getFraction方法中需要传递4个参数,那么它们分别代表什么呢?为什么得到参数不一样呢?

我们需要查看getFraction源码:

public float getFraction(int index, int base, int pbase, float defValue) { 
 index *= AssetManager.STYLE_NUM_ENTRIES; 
 final int[] data = mData; 
 final int type = data[index+AssetManager.STYLE_TYPE]; 
 if (type == TypedValue.TYPE_NULL) { 
 return defValue; 
 } else if (type == TypedValue.TYPE_FRACTION) { 
 return TypedValue.complexToFraction( 
 data[index+AssetManager.STYLE_DATA], base, pbase); 
 } 
 throw new UnsupportedOperationException("Can't convert to fraction: type=0x" 
 + Integer.toHexString(type)); 
 }

通过查看源码我可以知道第一个参数和第四参数明白什么意思,第二参数和第三个参数目前我们知道和我们最终返回结果相关,我只有继续往下查看源码:

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

哦!通过查看源码我们知道了,当我们设置参数是COMPLEX_UNIT_FRACTION的时候需要*第二个参数base,当我们设置参数是COMPLEX_UNIT_FRACTION_PARENT的时候需要*第三个参数pbase。p代表父容器父布局。

现在我们在看一下我们的例子,当我们设置30%的时候,需要0.3 * 2 = 0.6我们看一下结果是0.599999,当我们设置30%p的时候,需要0.3 * 4 = 1.2我们看一下结果是1.199999,最终返回是一个浮点数。同时我们在看一下COMPLEX_UNIT_FRACTION和COMPLEX_UNIT_FRACTION_PARENT的源码解释就可以明白了。

/** {@link #TYPE_FRACTION} complex unit: A basic fraction of the overall
     *  size. */
    public static final int COMPLEX_UNIT_FRACTION = 0;
    /** {@link #TYPE_FRACTION} complex unit: A fraction of the **parent** size. */
    public static final int COMPLEX_UNIT_FRACTION_PARENT = 1;

10、dimension 代表尺寸值

在attr.xml中我们可以<attr name="mDimension" format="dimension"/>

在我们布局文件中我们可以lgy:mDimension="32dp",

我们在代码中获取我们设置对应值

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.myTextView); 
 int mColor = typedArray.getColor(R.styleable.myTextView_mColor, Color.RED); 
 Log.i(TAG,"mColor:" + mColor); 
 boolean mBoolean = typedArray.getBoolean(R.styleable.myTextView_mBoolean, false); 
 Log.i(TAG, "mBoolean:" + mBoolean); 
 float mFloat = typedArray.getFloat(R.styleable.myTextView_mFloat,0.0f); 
 Log.i(TAG,"mFloat:" + mFloat); 
 int mInteger = typedArray.getInteger(R.styleable.myTextView_mInteger,1); 
 Log.i(TAG,"mInteger:" + mInteger); 
 int mInt = typedArray.getInt(R.styleable.myTextView_mInteger,2); 
 Log.i(TAG,"mInt:" + mInt); 
 String mString = typedArray.getString(R.styleable.myTextView_mString); 
 Log.i(TAG,"mString:" + mString); 
 int mEnum = typedArray.getInteger(R.styleable.myTextView_mEnum,5); 
 Log.i(TAG,"mEnum:" + mEnum); 
 int mEnumInt = typedArray.getInt(R.styleable.myTextView_mEnum,7); 
 Log.i(TAG,"mEnumInt:" + mEnumInt); 
 int mFlag = typedArray.getInteger(R.styleable.myTextView_mFlag,1); 
 Log.i(TAG,"mFlag:" + mFlag); 
 int mFlagInt = typedArray.getInt(R.styleable.myTextView_mFlag,1); 
 Log.i(TAG,"mFlagInt:" + mFlagInt); 
 int mReference = typedArray.getResourceId(R.styleable.myTextView_mReference,0); 
 Log.i(TAG,"mReference:" + mReference); 
 float mFraction = typedArray.getFraction(R.styleable.myTextView_mFraction,2,4,0); 
 Log.i(TAG,"mFraction:" + mFraction); 
 float mDimension = typedArray.getDimension(R.styleable.myTextView_mDimension, 14f); 
 Log.i(TAG, "mDimension:" + mDimension); 
 typedArray.recycle();

运行代码结果图:

navigationItem 自定义_xml_11

我们设置lgy:mDimensinotallow=”32dp”不同单位得到的值是不相同的。

32dp –>01-03 03:49:23.800 10694-10694/com.lgy.typearray I/MyTextView: mDimension:48.0 
 32sp –>01-03 03:53:43.210 14638-14638/com.lgy.typearray I/MyTextView: mDimension:48.0 
 32px –>01-03 03:54:30.430 15446-15446/com.lgy.typearray I/MyTextView: mDimension:32.0 
 32pt –>01-03 03:57:24.300 18042-18042/com.lgy.typearray I/MyTextView: mDimension:120.41481 
 32in –>01-03 03:58:07.660 18733-18733/com.lgy.typearray I/MyTextView: mDimension:8669.866 
 32mm –>01-03 03:59:17.210 19773-19773/com.lgy.typearray I/MyTextView: mDimension:341.3333

为什么设置不同单位得到值不同呢?这也需要查看源码:

public float getDimension(int index, float defValue) {
        index *= AssetManager.STYLE_NUM_ENTRIES;
        final int[] data = mData;
        final int type = data[index+AssetManager.STYLE_TYPE];
        if (type == TypedValue.TYPE_NULL) {
            return defValue;
        } else if (type == TypedValue.TYPE_DIMENSION) {
            return TypedValue.complexToDimension(
                data[index+AssetManager.STYLE_DATA], mResources.mMetrics);
        }

        throw new UnsupportedOperationException("Can't convert to dimension: type=0x"
                + Integer.toHexString(type));
    }

此时看不出什么门道来,继续往下看TypedValue.complexToDimension方法

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

继续看applyDimension方法

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

到此豁然开朗了吧!
获取尺寸的方法还有getDimensionPixelSize方法和getDimensionPixelOffset方法。那么它们有什么不同呢?
再一次通过查看源码我就可以得出结论.

public int getDimensionPixelOffset(int index, int defValue) {
        index *= AssetManager.STYLE_NUM_ENTRIES;
        final int[] data = mData;
        final int type = data[index+AssetManager.STYLE_TYPE];
        if (type == TypedValue.TYPE_NULL) {
            return defValue;
        } else if (type == TypedValue.TYPE_DIMENSION) {
            return TypedValue.complexToDimensionPixelOffset(
                data[index+AssetManager.STYLE_DATA], mResources.mMetrics);
        }

        throw new UnsupportedOperationException("Can't convert to dimension: type=0x"
                + Integer.toHexString(type));
    }
public int getDimensionPixelSize(int index, int defValue) {
        index *= AssetManager.STYLE_NUM_ENTRIES;
        final int[] data = mData;
        final int type = data[index+AssetManager.STYLE_TYPE];
        if (type == TypedValue.TYPE_NULL) {
            return defValue;
        } else if (type == TypedValue.TYPE_DIMENSION) {
            return TypedValue.complexToDimensionPixelSize(
                data[index+AssetManager.STYLE_DATA], mResources.mMetrics);
        }

        throw new UnsupportedOperationException("Can't convert to dimension: type=0x"
                + Integer.toHexString(type));
    }

通过源码知道2个方法分别都调用了TypedValue.complexToDimensionPixelOffset,TypedValue.complexToDimensionPixelSize,继续看源码:

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

最终2个方法也都调用了applyDimension方法,只不过两者调用了applyDimension方法强制转换int,complexToDimensionPixelSize方法得到值之后又做了简单处理。
那么现在我们可以知道getDimension、getDimensionPixelSize、getDimensionPixelOffset三者区别:
相同点:不同单位尺寸设置得到不同结果。都会调用applyDimension方法。
不同点:getDimension返回float类型,getDimensionPixelSize、getDimensionPixelOffset都是返回int类型。