自定义属性
自定义属性,遵循以下几步:
1,自定义一个CustomView类
2,编写values/attrs.xml,在其中编写标签元素
3,在布局文件中CustomView使用自定义的属性
4,在CustomView的构造方法中通过TypedArray获取
举个栗子:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="rightPadding" format="dimension" />
<declare-styleable name="CustomView">
<attr name="rightPadding" />
</declare-styleable>
</resources>
可以看到,我们先是定义了一个属性rightPadding,然后又在CustomView中引用了这个属性。下面说明一下:
首先,我们可以在declare-stylable标签中直接定义属性而不需要引用外部定义好的属性,但是为了属性的重用,我们可以选择上面的这种方法:先定义,后引用;
declare-stylable标签只是为了给自定义属性分类。一个项目中可能有多个自定义控件,但只能有一个attr.xml文件,因此我们需要对不同自定义控件中的自定义属性进行分类,这也是为什么declare-stylable标签中的name属性往往定义成自定义控件的名称;
所谓的在declare-stylable标签中的引用,就是去掉了外部定义的format属性,如果没有去掉format,则会报错;如果外部定义中没有format而在内部引用中又format,也一样会报错。
常用的format类型:
1) string:字符串类型;
2) integer:整数类型;
3) float:浮点型;
4) dimension:尺寸,后面必须跟dp、dip、px、sp等单位;
5) Boolean:布尔值;
6) reference:引用类型,传入的是某一资源的ID,必须以“@”符号开头;
7) color:颜色,必须是“#”符号开头;
8) fraction:百分比,必须是“%”符号结尾;
9) enum:枚举类型
下面对format类型说明几点:
format中可以写多种类型,中间使用“|”符号分割开,表示这几种类型都可以传入这个属性;
enum类型的定义示例如下代码所示:
<resources>
<attr name="orientation">
<enum name="horizontal" value="0" />
<enum name="vertical" value="1" />
</attr>
<declare-styleable name="CustomView">
<attr name="orientation" />
</declare-styleable>
</resources>
使用时通过getInt()方法获取到value并判断,根据不同的value进行不同的操作即可。
使用自定义属性
在XML布局文件中使用自定义的属性时,我们需要先定义一个namespace。Android中默认的namespace是android,因此我们通常可以使用“android:xxx”的格式去设置一个控件的某个属性,android这个namespace的定义是在XML文件的头标签中定义的,通常是这样的:
xmlns:android="http://schemas.android.com/apk/res/android"
我们自定义的属性不在这个命名空间下,因此我们需要添加一个命名空间。
自定义属性的命名空间如下:
xmlns:app="http://schemas.android.com/apk/res-auto"
可以看出来,除了将命名空间的名称从android改成app之外,就是将最后的“res/android”改成了“res-auto”。
注:自定义namespace的名称可以自己定义,不一定非得是app。
获取自定义属性
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomView, defStyleAttr, 0);
int indexCount = a.getIndexCount();
for (int i = 0; i < indexCount; i++) {
int attr = a.getIndex(i);
switch (attr) {
case R.styleable.CustomView_rightPadding:
mMenuRightPadding = a.getDimensionPixelSize(attr, 0);
break;
}
}
a.recycle();
}
这里需要说明一下:
获取自定义属性的代码通常是在三个参数的构造方法中编写的(具体为什么是三个参数的构造方法,下面的章节中会有解释);
在获取TypedArray对象时就为其绑定了该自定义View的自定义属性集(CustomView),通过getIndexCount()方法获取到自定义属性的数量,通过getIndex()方法获取到某一个属性,最后通过switch语句判断属性并进行相应的操作;
在TypedArray使用结束后,需要调用recycle()方法回收它。