您的位置:首页 > 移动开发 > Android开发

Android自定义控件(特效三) 自定义View实现图片验证码

2016-05-11 17:25 651 查看
之前在一些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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: