Android本地验证码的生成代码
程序员文章站
2022-03-20 22:44:46
android客户端生成本地验证码主要用来限制用户随意按请求按钮,其实该示例也是来对自定义view的练练手而已,先给出效果图吧其中可定制:*干扰线数目*干扰点数目*背景颜色*验证码字体大小及字数相信以...
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步骤,这里就给出源码地址,有需要的就去看看。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。