本来是想学习一下张鸿样的自定义View的,但是看了以后,觉得楼主这篇还不错,就拿来改了改,改成了验证码,希望对你们有帮助!
先来看看自定义View的一般步骤:
- 先把自己需要的属性在(attrs.xml)进行定义,比如
<declare-styleable name="MTextView_One">
<attr name="titleText" format="string" />
<attr name="titleTextViewColor" format="color" />
<attr name="titleTextSize" format="dimension" />
</declare-styleable>
- 然后自定义名字继承View
- 获取自定义的熟悉
- 重写onMeasure方法
重写onDraw方法
来一个效果图(不会做动态图,将就看)
“`
源码下载(项目是在AndroidStudio环境下运行的噢)
点击这里下载源码
/**
* Created by wangjilei on 2015/11/24.
* 功能:自定义View实现验证码
*/
public class MTextView_One extends View {
private String mTitleText;//文本
private int mTitleTextColor;//文本的颜色
private int mTitleTextSize;//文本的大小
private Rect mBound;//绘制时控制文本绘制的范围
private Paint mPaint;//画笔
private int width = 0;
private int height = 0;
public static final int POINT_NUM = 100;//点数设置(用于添加噪点)
public static final int LINE_NUM = 10;//线条数
public MTextView_One(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MTextView_One(Context context) {
this(context, null);
}
/**
* 获得我自定义的样式属性
*
* @param context
* @param attrs
* @param defStyle
*/
public MTextView_One(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
/**
* 获得我们所定义的自定义样式属性
*/
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MTextView_One, defStyle, 0);
int n = a.getIndexCount();
for (int i = 0; i < n; i++) {
int attr = a.getIndex(i);
switch (attr) {
case R.styleable.MTextView_One_titleText:
mTitleText = a.getString(attr);
break;
case R.styleable.MTextView_One_titleTextViewColor:
// 默认颜色设置为黑色
mTitleTextColor = a.getColor(attr, Color.BLUE);
break;
case R.styleable.MTextView_One_titleTextSize:
// 默认设置为16sp,TypeValue也可以把sp转化为px
mTitleTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
break;
}
}
a.recycle();
init();
}
private void init() {
/**
* 获得绘制文本的宽和高
*/
mPaint = new Paint();
mPaint.setTextSize(mTitleTextSize);
// mPaint.setColor(mTitleTextColor);
mBound = new Rect();
mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound);
/**
*点击自动改变数字
*/
this.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mTitleText = CheckGetUtil.randomText();
postInvalidate();
Intent intent = new Intent();
intent.putExtra("code", mTitleText);
}
});
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
/**
* 设置宽度
*/
int specMode = MeasureSpec.getMode(widthMeasureSpec);
int specSize = MeasureSpec.getSize(widthMeasureSpec);
switch (specMode) {
case MeasureSpec.EXACTLY:// 明确指定了
width = getPaddingLeft() + getPaddingRight() + specSize;
break;
case MeasureSpec.AT_MOST:// 一般为WARP_CONTENT
width = getPaddingLeft() + getPaddingRight() + mBound.width();
break;
}
/**
* 设置高度
*/
specMode = MeasureSpec.getMode(heightMeasureSpec);
specSize = MeasureSpec.getSize(heightMeasureSpec);
switch (specMode) {
case MeasureSpec.EXACTLY:// 明确指定了
height = getPaddingTop() + getPaddingBottom() + specSize;
break;
case MeasureSpec.AT_MOST:// 一般为WARP_CONTENT
height = getPaddingTop() + getPaddingBottom() + mBound.height();
break;
}
setMeasuredDimension(width, height);
}
@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() / 2, getHeight() / 2 + mBound.height() / 2, mPaint);
//绘制圆形噪点
int[] point;
mPaint.setColor(Color.RED);
for (int i = 0; i < POINT_NUM; i++) {
point = CheckGetUtil.getPoint(height, width);
canvas.drawCircle(point[0], point[1], 2, mPaint);
}
//绘制直线
mPaint.setColor(Color.BLUE);
int[] line;
for (int i = 0; i < LINE_NUM; i++) {
line = CheckGetUtil.getLine(height, width);
canvas.drawLine(line[0], line[1], line[2], line[3], mPaint);
}
}
}