之前在一些APP上看到图片验证码的效果,百度后发现网上大多数的代码都是写了一个Bitmap工具类来实现的,于是,今天尝试用自定义View来实现该效果
先上图:
先来说说思路,首先画一个大的背景图,然后生成验证码,最后在图中画出随机生成的验证码,以及干扰的线条
先写个View,继承View并实现构造方法、onDraw()
在OnDraw里,先来画一个大的背景图
canvas.drawColor(Color.rgb(219, 204, 133));
接下来,就是生成验证码了,这里我的验证码是由0-9、a-z、A-Z组成的,代码如下:
private static final char[] CODES = { '0', '1', '2', '3', '4', '5', '6',
'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z' };
StringBuilder buffer = new StringBuilder();
for (int i = 0; i < 4; i++) {
buffer.append(CODES[random.nextInt(CODES.length)]);
}
然后buffer.toString()就是我们随机生成的验证码了。
最后,在onDraw里画出我们的验证码,因为验证码的位置、是否加粗、颜色都需要随机,所以代码如下:
CODE_X += PADDING_X + random.nextInt(RANDOM_MAX_X);// 随机生成验证码X轴的位置
CODE_Y = PADDING_Y + random.nextInt(RANDOM_MAX_Y);// 随机生成验证码Y轴的位置
paint.setColor(randomColor());
paint.setFakeBoldText(random.nextBoolean()); // 随机粗体/非粗体
canvas.drawText(myCode.charAt(i) + "", CODE_X, CODE_Y, paint);
这样,就画出了验证码,然后我们可以再画出干扰的线条
int startX = random.nextInt(WIDTH); // 线条起始X坐标
int startY = random.nextInt(HEIGHT); // 线条起始Y坐标
int stopX = random.nextInt(WIDTH); // 线条结束X坐标
int stopY = random.nextInt(HEIGHT); // 线条结束Y坐标
paint.setStrokeWidth(2);// 设置线条的粗
paint.setColor(randomColor());// 设置线条颜色
canvas.drawLine(startX, startY, stopX, stopY, paint);// 画干扰线条
以上就是主要代码,其实代码都很简单,只要思路明确了,做起来还是很容易的
完整代码:
import java.util.Random;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
/**
* 自定义验证码
*
* @author 帽檐遮不住阳光
* @Date 2016/5/11
*
*/
public class MyView extends View {
/**
* 验证码长度
*/
private final int CODELENGTH = 4;
/**
* 验证码字体大小
*/
private final int TEXTZISE = 40;
/**
* 干扰线条的数目
*/
private final int LINENUM = 5;
/**
* 验证码X坐标
*/
private int CODE_X;
/**
* 验证码Y坐标
*/
private int CODE_Y;
/**
* 验证码每个字符X轴之间的间距
*/
private final int PADDING_X = 20;
/**
* 验证码每个字符Y轴之间的间距
*/
private final int PADDING_Y = 25;
/**
* 每次随机生成验证码时X轴最大值
*/
private final int RANDOM_MAX_X = 20;
/**
* 每次随机生成验证码时Y轴最大值
*/
private final int RANDOM_MAX_Y = 40;
/**
* 如果State为True,则随机生成验证码 如果State为False,则生成用户输入框输入的验证码
*/
private boolean state = true;
/**
* 验证码背景框的宽
*/
private final int WIDTH = 160;
/**
* 验证码背景框的高
*/
private final int HEIGHT = 100;
/**
* 验证码
*/
private String myCode;
Paint paint;
private Random random = new Random();
private static final char[] CODES = { '0', '1', '2', '3', '4', '5', '6',
'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z' };
public MyView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
paint = new Paint();
}
@Override
protected void onDraw(Canvas canvas) {
CODE_X = 0;// 将x轴位置设为0
paint.setTextSize(TEXTZISE);// 设置字体大小
canvas.drawColor(Color.rgb(219, 204, 133));// 背景颜色
if (state) {
// 如果为True 则随机生成验证码,否则使用用户输入的验证码
myCode = createCode();
}
// 画验证码
for (int i = 0; i < CODELENGTH; i++) {
CODE_X += PADDING_X + random.nextInt(RANDOM_MAX_X);// 随机生成验证码X轴的位置
CODE_Y = PADDING_Y + random.nextInt(RANDOM_MAX_Y);// 随机生成验证码Y轴的位置
paint.setColor(randomColor());
paint.setFakeBoldText(random.nextBoolean()); // 随机粗体/非粗体
canvas.drawText(myCode.charAt(i) + "", CODE_X, CODE_Y, paint);
}
// 画干扰线条
for (int i = 0; i < LINENUM; i++) {
drawLine(canvas, paint);
}
}
/**
* 随机生成验证码
*
* @return
*/
private String createCode() {
StringBuilder buffer = new StringBuilder();
for (int i = 0; i < CODELENGTH; i++) {
buffer.append(CODES[random.nextInt(CODES.length)]);
}
return buffer.toString();
}
/***
* 画干扰线条
*
* @param canvas
* @param paint
*/
private void drawLine(Canvas canvas, Paint paint) {
int startX = random.nextInt(WIDTH); // 线条起始X坐标
int startY = random.nextInt(HEIGHT); // 线条起始Y坐标
int stopX = random.nextInt(WIDTH); // 线条结束X坐标
int stopY = random.nextInt(HEIGHT); // 线条结束Y坐标
paint.setStrokeWidth(2);// 设置线条的粗
paint.setColor(randomColor());// 设置线条颜色
canvas.drawLine(startX, startY, stopX, stopY, paint);// 画干扰线条
}
/***
* 随机生成RGB
*
* @return
*/
private int randomColor() {
int red = random.nextInt(256);
int green = random.nextInt(256);
int blue = random.nextInt(256);
return Color.rgb(red, green, blue);
}
/**
* 刷新验证码
*/
public void refresh(boolean userState, String Code) {
myCode = Code;
state = userState;
invalidate();
}
public String getCode() {
return myCode;
}
}
Demo: http://download.csdn.net/detail/qq_18612815/9516939