Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android - 本地驗證碼的生成

Android - 本地驗證碼的生成

編輯:關於Android編程

android客戶端生成本地驗證碼主要用來限制用戶隨意按請求按鈕,其實該示例也是來對自定義view的練練手而已,先給出效果圖吧

這裡寫圖片描述

其中可定制:

*干擾線數目
*干擾點數目
*背景顏色
*驗證碼字體大小及字數<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPs/g0MXS1MnPv8nS1ML61+PSu7DjtcTQ6NKqwcuwyaOssru5u7XEu7C/ydfU0NDM7bzTo6zPwsPmvs3AtL2yyrXP1rXEsr3W6MHLPC9wPg0KPGg0IGlkPQ=="繼承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 * 文件,並加上自定義的屬性,如下:

<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">
    </attr></attr></attr></attr></attr></declare-styleable>
</resources></code>

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(),繪制圖形

繪制驗證碼文本字符串,干擾點,干擾線,生成驗證碼的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;
}
實現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步驟,這裡就給出源碼地址,有需要的就去看看https://github.com/myloften/VerificationCodeSample

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved