欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android本地验证码的生成代码

程序员文章站 2022-03-20 22:44:46
android客户端生成本地验证码主要用来限制用户随意按请求按钮,其实该示例也是来对自定义view的练练手而已,先给出效果图吧其中可定制:*干扰线数目*干扰点数目*背景颜色*验证码字体大小及字数相信以...

android客户端生成本地验证码主要用来限制用户随意按请求按钮,其实该示例也是来对自定义view的练练手而已,先给出效果图吧

Android本地验证码的生成代码

其中可定制:

*干扰线数目
*干扰点数目
*背景颜色
*验证码字体大小及字数

相信以上可以满足一般的需要了吧,不够的话可自行添加,下面就来讲实现的步骤了

继承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 验证码