自定义View(一):自定义属性获取

1、什么是自定义属性

在Android的开发过程中,我们在写xml布局的时候会用到许多组件的属性来控制组件的外观和特点,那其中到底是怎么实现的呢,今天我们来探究一下如何编写自定义属性。

2、新建一个类MyView继承View

我们可以看到View有四个构造方法

自定义View(一):自定义属性获取
第一个构造方法是最简单的构造方法,在Java代码中新建一个View对象且只有context一个参数的时候会调用。

第二个构造方法在自定义属性中至关重要,当一个组件在xml中引用的时候就会调用调用该方法。

第三个构造方法和第四个构造方法在定义主题的时候回调用,在View指定了一个主题的情况下,View的某些属性尽管我们不去赋值它也会有值,这时就依靠这两个构造方法去实现,在不同的情况下,这两个构造方法会有不同的优先级去调用。

3、在values下新建一个attr.xml,其内容如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyView">
        <!--name:自定义属性名,format:自定义属性数据类型-->
        <attr name="mtext" format="string"></attr>
        <attr name="mcolor" format="color"></attr>
        <attr name="msize" format="dimension"></attr>
        <attr name="mfloat" format="float"></attr>
    </declare-styleable>
</resources>

format有10种数据类型,如下:

string,顾名思义,字符串类型

dimension,尺寸类型

 boolean,布尔类型

color,颜色类型

enum,枚举类型

flag,位或运算

 fraction,百分数

integer,整型

reference,参考某一资源ID

4、在xml中引用MyView


<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.attrdemo.MainActivity">

    <com.attrdemo.MyView
        android:layout_height="200dp"
        android:layout_width="250dp"
        android:layout_gravity="center"
        android:background="@android:color/darker_gray"

        app:mcolor="@color/colorPrimary"
        app:msize="16px"
        app:mtext="你地好吗"
        app:mfloat="6.66"/>
</FrameLayout>

可以看到我们刚刚在attr.xml中定义的新属性都在MyView中得以调用,值得关注的是

xmlns:app="http://schemas.android.com/apk/res-auto"

这句的作用是app:以自动查找的方式引入一个命名空间。

5、在Java中获取这些定义了的属性

话不多说,贴代码


private String mtext;
private int mcolor;
private int msize;
private float mfloat;

public MyView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.MyView);
    mtext = array.getString(R.styleable.MyView_mtext);
    mcolor = array.getColor(R.styleable.MyView_mcolor, Color.BLACK);
    msize = array.getDimensionPixelSize(R.styleable.MyView_msize, 100);
    mfloat=array.getFloat(R.styleable.MyView_mfloat, (float) 1.234);
    array.recycle();  //释放资源
    Log.i("debug","text:"+mtext);
    Log.i("debug","color:"+mcolor);
    Log.i("debug","size:"+msize);
    Log.i("debug","float:"+mfloat);
}

可以看到通过context类的obainStyledAttributes()方法获取TypedArray对象,再通过TypedArray对象的get方法获取属性的值,在往后的onMeasure()和onDraw()中会有用到。
程序运行结果如下:

自定义View(一):自定义属性获取

6、源码链接

https://github.com/Hasagit/AttrDemo.git