1.先在资源文件中定义要使用的属性
新建资源文件,在values文件中右键,new value XML文件,命名为attrs.xml(至于这个为什么命名为attrs,我在网上也没有找到,但是如果将attrs换成别的名字,也能达到同样的效果)
资源文件的内容如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="mtitleText" format="string"/>
<attr name="mtitleTextColor" format="color"/>
<attr name="mtitleTextSize" format="dimension"/>
<declare-styleable name="CustomTitleView">
<attr name="mtitleText"/>
<attr name="mtitleTextColor"/>
<attr name="mtitleTextSize"/>
</declare-styleable>
</resources>
将<attr name="mtitleText" format="string">写到<declare-styleable>外面,表示声明,如此后只用在里面要使用的时候使用即可,表示可以使用在多个<declare-styleable>中
另外一种写法是
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="mTopBar">
<attr name="mtitle" format="string"/>
<attr name="mtitleTextSize" format="dimension"/>
<attr name="mtitleTextColor" format="color"/>
<attr name="mleftTextColor" format="color"/>
<attr name="mleftBackground" format="reference|color"/>
<attr name="mleftText" format="string"/>
<attr name="mrightTextColor" format="color"/>
<attr name="mrightBackground" format="reference|color"/>
<attr name="mrightText" format="string"/>
</declare-styleable>
</resources>
再来看其中的format,表示的是类型
有:string,color,demension,integer,enum,reference,float,boolean,fraction,flag
2.写自定义类
public class CustomView extends View {
private String mTitleText;
private int mTitleTextColor;
private int mTitleTextSize;
private Rect mBound;
private Paint mPaint;
public CustomView(Context context) {
this(context, null);
}
public CustomView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a=context.getTheme().obtainStyledAttributes(attrs,R.styleable.CustomTitleView,defStyleAttr,0);
int n=a.getIndexCount();
for(int i=0;i<n;i++){
int attr=a.getIndex(i);
switch(attr)
{
case R.styleable.CustomTitleView_mtitleText:
mTitleText=a.getString(attr);
break;
case R.styleable.CustomTitleView_mtitleTextColor:
mTitleTextColor=a.getColor(attr, Color.BLACK);
break;
case R.styleable.CustomTitleView_mtitleTextSize:
mTitleTextSize=a.getDimensionPixelSize(attr,(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,16,getResources().getDisplayMetrics()));
break;
}
}
a.recycle();
mPaint=new Paint();
mPaint.setTextSize(mTitleTextSize);
//getTextBounds第一个参数接收一个字符文本,第二根参数为首字符,第三个参数为尾字符,第四个参数为矩形变量,接收包括文本的最小矩形
mBound=new Rect();
mPaint.getTextBounds(mTitleText,0,mTitleText.length(),mBound);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
//画一个矩形,填充色为黄色
mPaint.setColor(Color.YELLOW);
canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),mPaint);
//写文本
mPaint.setColor(mTitleTextColor);
//传入的为文本字符串,宽度,高度,画笔
canvas.drawText(mTitleText,getWidth()/2-mBound.width(),getHeight()/2+mBound.height()/2,mPaint);
}
}
这个需要说明的是三个构造函数
如果在Code中实例化一个View会调用第一个构造函数,如果在xml中定义会调用第二个构造函数,而第三个函数系统是不调用的,要由View(我们自定义的或系统预定义的View,如此处的CustomTextView和Button)显式调用
3.我们是在xml中定义的,如下
<com.example.administrator.musicplay.CustomView
android:layout_width="200dp"
android:layout_height="100dp"
custom:mtitleText="3712"
custom:mtitleTextColor="#ff0000"
custom:mtitleTextSize="40sp"
/>
当然在这之前一定要加上
xmlns:custom="http://schemas.android.com/apk/res-auto"
表名用到了外部的属性,其中custon是自定义的(任取),与使用的对应。
4.最后在activity中调用即可。