自定义View的分类
1.继承View重写onDraw方法
2.继承ViewGroup派生特殊的Layout
3.继承特定的View(比如TextView)
4.继承特定的ViewGroup(比如LinearLayout)
自定义View的步骤:
1.自定义View的属性
2.在View的构造方法中获得自定义的属性
3.重写onMesure(非必需)
4.重写onDraw
1.自定义属性,首先在res/values/下建立attrs文件,并在里面定义属性
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="customText" format="string"/>
<attr name="customTextColor" format="color"/>
<attr name="customTextSize" format="dimension"/>
<declare-styleable name="CustomView">
<attr name="customText"/>
<attr name="customTextColor"/>
<attr name="customTextSize"/>
</declare-styleable>
</resources>
上面定义了字体 字体颜色 字体大小 从字面看出 format是取值类型
2.在View的构造方法中,获得自定义属性
重写三个构造方法,默认是使用两个参数的构造方法,因此让所有的构造方法调用三个参数的构造函数
public class CustomView extends View {
//文本
private String mCustomText;
//文本颜色
private int mCustomTextColor;
//文本大小
private int mCustomTextSize;
//绘制时控制文本绘制的范围
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 defstyle){
super(context,attrs,defstyle);
//获取自定义的自定义样式
TypedArray ta = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomView,defstyle,0);
//获取有多少个属性
int n = ta.getIndexCount();
for(int i=0;i < n;i++){
int attr = ta.getIndex(i);//获取具体的属性值
switch(attr){
case R.styleable.CustomView_customText:
mCustomText = ta.getString(attr);
break;
case R.styleable.CustomView_customTextColor:
mCustomTextColor = ta.getColor(attr, Color.RED);
break;
case R.styleable.CustomView_customTextSize:
mCustomTextSize = ta.getDimensionPixelSize(attr,(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,16,getResources().getDisplayMetrics()));
break;
}
}
ta.recycle();
//获得绘制文本的宽高
mPaint = new Paint();
mPaint.setTextSize(mCustomTextSize);
mBound = new Rect();
mPaint.getTextBounds(mCustomText,0,mCustomText.length(),mBound);
}
}
3.重写onDraw,onMesure方法
@Override
protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec){
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas)
{
//设置背景
mPaint.setColor(Color.BLACK);
canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);
mPaint.setColor(mCustomTextColor);
canvas.drawText(mCustomText, getWidth() / 2 - mBound.width() / 2, getHeight() / 2 + mBound.height() / 2, mPaint);
}
4.在布局文件声明自定义view
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.nova.customviewdemo.ui.MainActivity">
<com.nova.customviewdemo.view.CustomView
android:layout_width="120dp"
android:layout_height="100dp"
custom:customText="1111"
custom:customTextColor="#ff0000"
custom:customTextSize="40sp"
/>
</RelativeLayout>
此时的效果是:
就这样 一个带文字的矩形就描绘出来了