1.在res/values目录下定义attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomView">
<attr name="select_text_size" format="dimension" />
<attr name="isSelect" format="boolean" />
<attr name="defaultColor" format="color" />
<attr name="duration" format="integer" />
<attr name="text" format="string|reference" />
</declare-styleable>
</resources>
attr子元素:
定义具体的属性,format表示这个属性的值的类型,类型有以下几种:
1.reference:参考指定Theme中资源ID,这个类型意思就是你传的值可以是引用资源
2.string:字符串,如果你想别人既能直接写值也可以用类似"@string/test"引用资源的方式,可以写成format="string|reference"
3.Color:颜色
4.boolean:布尔值
5.dimension:尺寸值
6.float:浮点型
7.integer:整型
8.fraction:百分数
9.enum:枚举 ,如果你提供的属性只能让别人选择,不能随便传入,就可以写成这样
<attr name="language">
<enum name="china" value="1"/>
<enum name="English" value="2"/>
</attr>
10.flag:位或运算
declare-styleable子元素:
定义一个styleable对象,每个styleable对象就是一组attr属性的集合 注意:这里的name属性并不是一定要和自定义类名相同,只是为了好区分对应类的属性而已
注意:上面的属性资源文件定义了该属性之后,至于到底是哪个自定义View组件中来使用该属性,该属性到底能发挥什么作用, 就不归该属性资源文件管了,也就是说这个属性资源文件是个公共的,大家都可以用,但是为了方便管理,一般都是一个自定义View里的属性写成一个declare-styleable集合.属性资源所定义的属性到底可以返回什么作用,取决于自定义组件的代码实现
2.自定义类中使用
public class MyView extends View {
private Paint mPaint;
private static String mString;
public MyView(Context context) {
super(context);
mPaint = new Paint();
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint();
/* 这里取得declare-styleable集合 */
TypedArray typeArray = context.obtainStyledAttributes(attrs,
R.styleable.CustomView);
/* 这里从集合里取出相对应的属性值,第二参数是如果使用者没用配置该属性时所用的默认值 */
int textColor = typeArray.getColor(
R.styleable.CustomView_defaultColor, 0xff000000);
float textSize = typeArray.getDimension(
R.styleable.CustomView_select_text_size, 36);
mString = typeArray.getString(R.styleable.CustomView_text);
/* 设置自己的类成员变量 */
mPaint.setTextSize(textSize);
mPaint.setColor(textColor);
/* 关闭资源 */
typeArray.recycle();
}
public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mPaint = new Paint();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setStyle(Style.FILL);
canvas.drawRect(new Rect(10, 10, 190, 90), mPaint);
mPaint.setColor(Color.BLUE);
canvas.drawText("aaaa" + mString, 100, 110, mPaint);
}
}
3.使用自定义属性
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:myandroid="http://schemas.android.com/apk/res/com.example.myview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<com.example.myview.MyView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
myandroid:select_text_size="12sp"
myandroid:isSelect="true"
myandroid:text="@string/hello_world" >
</com.example.myview.MyView>
</RelativeLayout>
注意:java代码里那种取属性值的方式,那么在XML使用该组件的时候一定要为该自定义组件设置一个命名空间[xmlns:myandroid=”http://schemas.android.com/apk/res/cn.com.androidtest”],不然组件属性设置不了
命名空间写法:xmlns:空间名=”http://schemas.android.com/apk/res/自定义组件所在包名” ;包名是最顶层的包名
myandroid是自己定义的,和下面myandroid:text中的myandroid保持一致即可。