Android本地验证码的生成代码

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步骤,这里就给出源码地址,有需要的就去看看。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android栗子の图片验证码生成实例代码

    废话不多说了,下面一段代码给大家分享android 生成栗子图片验证码功能,具体代码如下所示: import java.util.Random; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; public class

  • android端实现验证码随机生成功能

    本文实例为大家分享了android端生成随机验证码的具体代码,供大家参考,具体内容如下 package com.nobeg.util; import java.util.Random; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Bitmap.

  • Android自定义控件深入学习 Android生成随机验证码

    在上一篇的文章中介绍了自定义控件的属性,详情见<详解Android自定义控件属性TypedArray以及attrs>.那么在这基础上实现随机验证码生成,里面的代码是自定义控件以及涉及到自定义view绘画. 1.先看实现的效果图 看到这个效果图是不是感觉还可以.那么就看看源码吧. 2.attr文件 <?xml version="1.0" encoding="utf-8"?> <resources> <attr name=&qu

  • Android自定义View绘制随机生成图片验证码

    本篇文章讲的是Android自定义View之随机生成图片验证码,开发中我们会经常需要随机生成图片验证码,但是这个是其次,主要还是想总结一些自定义View的开发过程以及一些需要注意的地方. 按照惯例先看看效果图: 一.先总结下自定义View的步骤: 1.自定义View的属性 2.在View的构造方法中获得我们自定义的属性 3.重写onMesure 4.重写onDraw 其中onMesure方法不一定要重写,但大部分情况下还是需要重写的 二.View 的几个构造函数 1.public CustomV

  • Android随机生成验证码

    Android随机生成验证码,Android利用随机数绘制不规则的验证码,加强用户登录或者注册的安全性. 具体思路如下: 在一块固定宽高的画布上,画上固定个数的随机数字和字母,再画上固定条数的干扰线 随机数和干扰线的颜色随机生成,随机数的样式随机生成. 界面效果如下: 1.生成随机数代码,Code.java: public class Code { //随机数数组 private static final char[] CHARS = { '2', '3', '4', '5', '6', '7'

  • Android本地验证码的生成代码

    android客户端生成本地验证码主要用来限制用户随意按请求按钮,其实该示例也是来对自定义view的练练手而已,先给出效果图吧 其中可定制: *干扰线数目 *干扰点数目 *背景颜色 *验证码字体大小及字数 相信以上可以满足一般的需要了吧,不够的话可自行添加,下面就来讲实现的步骤了 继承view,重写构造方法,并初始化所需参数 public class ValidationCode extends View { private Paint mTextPaint;//文字画笔 private Pai

  • Android本地验证码的简易实现方法(防止暴力登录)

    0.  前言  验证码无处不在,有人问我,你知道达芬奇密码下面是什么吗,对,答案就是达芬奇验证码. 验证码一个最主要的作用就是防止恶意暴力破解登录,防止不间断的登录尝试,有人说其实可以在服务器端对该终端进行登录间隔检测,如果间隔太短可以展示拒绝的姿态.但是还是本地验证码作用更加实在,可以减轻服务器端的压力.这篇将使用自定义View来实现一个如下效果的简易本地验证码.算是对自定义View知识的复习吧. 1.  布局结构  <RelativeLayout xmlns:android="http

  • Android绘制验证码的实例代码

    在前面仿华为加载动画.仿网易音乐听歌识曲-麦克风动画中,我们通过绘图的基础知识完成了简单的绘制.在本例中,我们将绘制常见的验证码. 一.效果图 二.知识点与思路分析 通过上面的效果图观察,我们可以看到里面有绘制的随机线条,随机绘制的验证码. 绘制线条,直线或曲线 绘制文本,生成的验证码文本的绘制 绘制圆点. 三.代码编写 /** * Created by Iflytek_dsw on 2017/7/3. */ public class IdentifyCodeUtil { private sta

  • Android获取验证码倒计时实现代码

    本文实例为大家分享了Android获取验证码倒计时的具体代码,供大家参考,具体内容如下 1. 验证码输入框和获取验证码按钮布局 xml代码: <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:background="@color/white" android:orientation="horizontal&q

  • Java验证码图片生成代码

    Java生成验证码图片的具体代码,供大家参考,具体内容如下 1.首先新建一各专门生成验证码图片的类VerifyCode: public class VerifyCode { private int w=70; private int h=35; private Random r=new Random(); //宋体,华文楷书,黑体,华文新魏,华文隶书,微软雅黑,楷体_GB2312,Times New Roman private String [] fontNames={"宋体",&qu

  • vue生成随机验证码的示例代码

    本文介绍了vue生成随机验证码的示例代码,分享给大家,具体如下: 样式自调,最终效果如图: 实现效果: 点击右边input框会自动切换,如果输入的值与字不同,则清空换一串随机数 HTML <input type="text" placeholder="请输入验证码" class="yanzhengma_input" @blur="checkLpicma" v-model="picLyanzhengma"

  • php生成4位数字验证码的实现代码

    在php中实现验证码还是很方便的,关键点在于掌握php gd库与session的用法. 纵观网上php 生成验证码的例子,无不是php gd库与session相结合,并利用php 生成随机数的方法来完成. PHP验证码,可以分为很多种,包括 php 图片验证码,php 随机验证码,以及php 中文验证码等,根据不同的应用场合来使用不同的验证码. 这里分享一个php数字验证码,供大家参考. 4位数字验证码 /* *Filename:authpage.php */ session_start();

  • python图片验证码生成代码

    本文实例为大家分享了python图片验证码实现代码,供大家参考,具体内容如下 #!/usr/bin/env python # -*- coding: UTF-8 -*- import random from PIL import Image, ImageDraw, ImageFont, ImageFilter try: import cStringIO as StringIO except ImportError: import StringIO _letter_cases = "abcdefg

  • Android 利用 APT 技术在编译期生成代码

    APT(Annotation Processing Tool 的简称),可以在代码编译期解析注解,并且生成新的 Java 文件,减少手动的代码输入.现在有很多主流库都用上了 APT,比如 Dagger2, ButterKnife, EventBus3 等,我们要紧跟潮流,与时俱进呐! (ง •̀_•́)ง 下面通过一个简单的 View 注入项目 ViewFinder 来介绍 APT 相关内容,简单实现了类似于ButterKnife 中的两种注解 @BindView 和 @OnClick . 项目

随机推荐