編輯:關於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;
}
/**
* 獲取驗證碼
*
* @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
相信大家都有使用九宮格解鎖,比如在設置手機安全項目中,可以使用九宮格解鎖,提高安全性,以及在使用支付功能的時候,為了提高安全使用九宮鎖,今天就為大家介紹Android實現
The APK file does not exist on disk.Error while Installing APK解決方案:Android Studio獲取SH
本文和大家一起做一個帶箭頭的圓角矩形菜單,大概長下面這個樣子: 要求頂上的箭頭要對准菜單錨點,菜單項按壓反色,菜單背景色和按壓色可配置。最簡單的做法就是讓UX給
1.下載源碼 這部分網上有大量的資料,我就不重新寫了,這是我參考的文章:《Windows平台下Android源碼的下載》 一般來說,跟著上面文章的講解操作