Android本地验证码的生成代码
- 作者: 涩花喵
- 来源: 51数据库
- 2021-08-10
android客户端生成本地验证码主要用来限制用户随意按请求按钮,其实该示例也是来对自定义view的练练手而已,先给出效果图吧

其中可定制:
*干扰线数目
*干扰点数目
*背景颜色
*验证码字体大小及字数
相信以上可以满足一般的需要了吧,不够的话可自行添加,下面就来讲实现的步骤了
继承view,重写构造方法,并初始化所需参数
public class validationcode extends view {
private paint mtextpaint;//文字画笔
private paint mpointpaint;//干扰点画笔
private paint mpathpaint;//干扰线画笔
private paint mbitmappaint;//bitmap图画笔
private string mcodestring;//随机验证码
private int mcodecount;//验证码位数
private float mtextsize;//验证码字符大小
private int mpointnumber;//干扰点数目
private int mlinenumber;//干扰线数目
private int mbackground;//背景颜色
private float mtextwidth;//验证码字符串的显示宽度
private static int mwidth;//控件的宽度
private static int mheight;//控件的高度
private static random mrandom = new random();
private bitmap bitmap = null;//生成验证码图片
public validationcode(context context) {
this(context, null);
}
public validationcode(context context, attributeset attrs) {
super(context, attrs);
getattrvalues(context, attrs);
init();
}
/**
* 获取布局文件中的值
*/
private void getattrvalues(context context, attributeset attrs) {
typedarray typedarray = context.obtainstyledattributes(attrs, r.styleable.validationcode);
mcodecount = typedarray.getinteger(r.styleable.validationcode_codecount, 4);
mpointnumber = typedarray.getinteger(r.styleable.validationcode_pointnumber, 100);
mlinenumber = typedarray.getinteger(r.styleable.validationcode_linenumber, 2);
mtextsize = typedarray.getdimension(r.styleable.validationcode_codetextsize, 20);
mbackground = typedarray.getcolor(r.styleable.validationcode_background,color.white);
typedarray.recycle();
}
@override
protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {
super.onmeasure(widthmeasurespec, heightmeasurespec);
setmeasureddimension(measurewidth(widthmeasurespec), measureheight(heightmeasurespec));
}
/**
* 初始化画笔
*/
private void init() {
//生成随机数字和字母组合
mcodestring = getvalidationcode(mcodecount);
//初始化文字画笔
mtextpaint = new paint();
mtextpaint.setstrokewidth(3);
mtextpaint.settextsize(mtextsize);
//初始化干扰点画笔
mpointpaint = new paint();
mpointpaint.setstrokewidth(4);
mpointpaint.setstrokecap(paint.cap.round);//设置断点处为圆形
//初始化干扰线画笔
mpathpaint = new paint();
mpathpaint.setstrokewidth(5);
mpathpaint.setcolor(color.gray);
mpathpaint.setstyle(paint.style.stroke);//设置画笔为空心
mpathpaint.setstrokecap(paint.cap.round);//设置断点处为圆形
//初始化bitmap画笔
mbitmappaint = new paint();
mbitmappaint.setcolor(color.red);
//取得验证码字符串显示的宽度值
mtextwidth = mtextpaint.measuretext(mcodestring);
}
}
getattrvalues方法是用来配置自定义的属性,需要在 values 中新建 * attrs.xml * 文件,并加上自定义的属性,如下:
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="validationcode"> <attr name="codecount" format="integer"/> <attr name="pointnumber" format="integer"/> <attr name="linenumber" format="integer"/> <attr name="codetextsize" format="dimension"/> <attr name="background" format="color"/> </declare-styleable> </resources>
onmeasure方法则是在你需要对自定义的view的大小做出处理时,通过setmeasureddimension设置该控件大小,下面给出重新定义的宽高代码块
/**
* 对view的宽高进行重新定义
*/
private int measurewidth(int measurespec) {
int result = 0;
int specmode = measurespec.getmode(measurespec);
int specsize = measurespec.getsize(measurespec);
if (specmode == measurespec.exactly) {
result = specsize;
} else {
result = (int) (mtextwidth * 2.0f);
if (specmode == measurespec.at_most) {
result = math.min(result, specsize);
}
}
return result;
}
private int measureheight(int measurespec) {
int result = 0;
int specmode = measurespec.getmode(measurespec);
int specsize = measurespec.getsize(measurespec);
if (specmode == measurespec.exactly) {
result = specsize;
} else {
result = (int) (mtextwidth / 1.5f);
if (specmode == measurespec.at_most) {
result = math.min(result, specsize);
}
}
return result;
}
重写ondraw(),绘制图形
1、绘制验证码文本字符串,干扰点,干扰线,生成验证码的bitmap图
/**
* 获取验证码
*
* @param length 生成随机数的长度
* @return
*/
public static string getvalidationcode(int length) {
string val = "";
random random = new random();
for (int i = 0; i < length; i++) {
//字母或数字
string code = random.nextint(2) % 2 == 0 ? "char" : "num";
//字符串
if ("char".equalsignorecase(code)) {
//大写或小写字母
int choice = random.nextint(2) % 2 == 0 ? 65 : 97;
val += (char) (choice + random.nextint(26));
} else if ("num".equalsignorecase(code)) {
val += string.valueof(random.nextint(10));
}
}
return val;
}
/**
* 生成干扰点
*/
private static void drawpoint(canvas canvas, paint paint) {
pointf pointf = new pointf(mrandom.nextint(mwidth) + 10, mrandom.nextint(mheight) + 10);
canvas.drawpoint(pointf.x, pointf.y, paint);
}
/**
* 生成干扰线
*/
private static void drawline(canvas canvas, paint paint) {
int startx = mrandom.nextint(mwidth);
int starty = mrandom.nextint(mheight);
int endx = mrandom.nextint(mwidth);
int endy = mrandom.nextint(mheight);
canvas.drawline(startx, starty, endx, endy, paint);
}
/**
1. 绘制验证码并返回
*/
private bitmap generatevalidate(){
if(bitmap != null && !bitmap.isrecycled()){
//回收并且置为null
bitmap.recycle();
bitmap = null;
}
//创建图片和画布
bitmap sourcebitmap = bitmap.createbitmap(mwidth,mheight, bitmap.config.argb_8888);
canvas canvas = new canvas(sourcebitmap);
//画背景颜色
canvas.drawcolor(mbackground);
//画上验证码
int length = mcodestring.length();
float charlength = mtextwidth / length;
for (int i = 1; i <= length; i++) {
int offsetdegree = mrandom.nextint(15);
//这里只会产生0和1,如果是1那么正旋转正角度,否则旋转负角度
offsetdegree = mrandom.nextint(2) == 1 ? offsetdegree : -offsetdegree;
canvas.save();
canvas.rotate(offsetdegree, mwidth / 2, mheight / 2);
//给画笔设置随机颜色
mtextpaint.setargb(255, mrandom.nextint(200) + 20, mrandom.nextint(200) + 20,
mrandom.nextint(200) + 20);
canvas.drawtext(string.valueof(mcodestring.charat(i - 1)), (i - 1) * charlength * 1.6f + 30,
mheight * 2 / 3f, mtextpaint);
canvas.restore();
}
//产生干扰效果1 -- 干扰点
for (int i = 0; i < mpointnumber; i++) {
mpointpaint.setargb(255, mrandom.nextint(200) + 20, mrandom.nextint(200) + 20,
mrandom.nextint(200) + 20);
drawpoint(canvas, mpointpaint);
}
//生成干扰效果2 -- 干扰线
for (int i = 0; i < mlinenumber; i++) {
mpathpaint.setargb(255, mrandom.nextint(200) + 20, mrandom.nextint(200) + 20,
mrandom.nextint(200) + 20);
drawline(canvas, mpathpaint);
}
canvas.save();
return sourcebitmap;
}
2、实现ondraw()方法,绘画出验证码
@override
protected void ondraw(canvas canvas) {
super.ondraw(canvas);
//获取控件的宽和高
mheight = getheight();
mwidth = getwidth();
if(bitmap == null){
bitmap = generatevalidate();
}
canvas.drawbitmap(bitmap,0,0,mbitmappaint);
}
添加触摸事件,点击切换验证码
@override
public boolean ontouchevent(motionevent event) {
switch (event.getaction()) {
case motionevent.action_down:
mcodestring = getvalidationcode(mcodecount);
bitmap = generatevalidate();
invalidate();
break;
default:
break;
}
return super.ontouchevent(event);
}
添加公开使用方法
我们总是需要提供给用户调用的方法,判断验证码是否一致之类的,方便用户进一步的操作,这里提供个几个方法
/**
* 判断验证码是否一致
*
* @string codestring
* 这里忽略大小写
*/
public boolean isequalsignorecase(string codestring) {
return mcodestring.equalsignorecase(codestring);
}
/**
* 判断验证码是否一致
* 不忽略大小写
*/
public boolean isequals(string codestring) {
return mcodestring.equals(codestring);
}
/**
* 外界控件调用刷新验证码图片
*/
public void refresh(){
mcodestring = getvalidationcode(mcodecount);
bitmap = generatevalidate();
invalidate();
}
以上就是生成本地验证码的一个简单的自定义view步骤,这里就给出源码地址,有需要的就去看看。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
热点文章
android中Bitmap用法(显示,保存,缩放,旋转)实例分析
12
android 仿微信聊天气泡效果实现思路
1
Android的尺度,drawable-xxxxxxx
2
Codeforces Round #656 (Div. 3) (C、D题)
1
Android之handler异步消息处理机制解析
6
GridView中图片显示出现上下间距过大,左右图片显示类似瀑布流的问题
0
AsyncTask的简单使用
5
两个简单Fragment之间的通信(三种方式)
18
uboot修改设置boot参数命令
41
android中实现从相册中一次性获取多张图片与拍照,并将选中的图片显示出来
2
