验证码

来源:互联网 发布:矩阵2范数怎么求 编辑:程序博客网 时间:2024/06/05 09:33

先看效果:

代码:

package com.example.yanzhengma;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.util.AttributeSet;import android.util.TypedValue;import android.view.View;import java.util.Random;public class AuthCodeView extends View {    public static final int POINT_NUM = 100;   // 点数设置    public static final int LINE_NUM = 2;// 线段数设置    private String mTitleText;  //文本    private int mTitleTextColor;   // 文本的颜色    private int mTitleTextSize; // 文本的大小    String[] mCheckNum = new String[4];    Random random = new Random();    private Rect mBound;//绘制时控制文本绘制的范围    private Paint mPaint;    public AuthCodeView(Context context) {        this(context, null);    }    public AuthCodeView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public AuthCodeView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.AuthCodeView, defStyle, 0);//获得我们所定义的自定义样式属性        //获取在attr文件下,名字为AuthCodeView的declare-styleable属性有几个        int n = a.getIndexCount();        for (int i = 0; i < n; i++) {            int attr = a.getIndex(i);            switch (attr) {                case R.styleable.AuthCodeView_titleText://这个属性可以不要,因为都是随机产生                    mTitleText = a.getString(attr);                    break;                case R.styleable.AuthCodeView_titleTextColor:                    mTitleTextColor = a.getColor(attr, Color.BLACK); // 默认颜色设置为黑色                    break;                case R.styleable.AuthCodeView_titleTextSize:                    // 默认设置为16sp,TypeValue也可以把sp转化为px                    mTitleTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));                    break;            }        }        a.recycle();        mTitleText = randomText();        /**         * 获得绘制文本的宽和高         */        mPaint = new Paint();        mPaint.setTextSize(mTitleTextSize);        mBound = new Rect();        mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound);        this.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                mTitleText = randomText();                postInvalidate();            }        });    }    //随机产生验证码    private String randomText() {        StringBuffer sbReturn = new StringBuffer();        for (int i = 0; i < 4; i++) {            StringBuffer sb = new StringBuffer();            int randomInt = random.nextInt(10);            mCheckNum[i] = sb.append(randomInt).toString();            sbReturn.append(randomInt);        }        return sbReturn.toString();    }    //获取验证码    public String getAuthCode() {        return mTitleText;    }    //重写这个方法,设置自定义view控件的大小    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int width = 0;        int height = 0;        /**         * 设置宽度         */        int specMode = MeasureSpec.getMode(widthMeasureSpec);        int specSize = MeasureSpec.getSize(widthMeasureSpec);        switch (specMode) {            case MeasureSpec.EXACTLY:// 明确指定了                width = getPaddingLeft() + getPaddingRight() + specSize;                break;            case MeasureSpec.AT_MOST:// 一般为WARP_CONTENT                width = getPaddingLeft() + getPaddingRight() + mBound.width();                break;        }        /**         * 设置高度         */        specMode = MeasureSpec.getMode(heightMeasureSpec);        specSize = MeasureSpec.getSize(heightMeasureSpec);        switch (specMode) {            case MeasureSpec.EXACTLY:// 明确指定了                height = getPaddingTop() + getPaddingBottom() + specSize;                break;            case MeasureSpec.AT_MOST:// 一般为WARP_CONTENT                height = getPaddingTop() + getPaddingBottom() + mBound.height();                break;        }        setMeasuredDimension(width, height);    }    @Override    protected void onDraw(Canvas canvas) {        mPaint.setColor(Color.BLUE);//画背景颜色        canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);        mPaint.setColor(mTitleTextColor);//划线        int[] line;        for (int i = 0; i < LINE_NUM; i++) {            mPaint.setStrokeWidth(5);  //设置线宽            line = getLine(getMeasuredHeight(), getMeasuredWidth());            canvas.drawLine(line[0], line[1], line[2], line[3], mPaint);        }        int[] point; // 绘制小圆点        int randomInt;        for (int i = 0; i < POINT_NUM; i++) {            //随机获取点的大小            randomInt = random.nextInt(5);            point = getPoint(getMeasuredHeight(), getMeasuredWidth());            canvas.drawCircle(point[0], point[1], randomInt, mPaint);        }        //绘制验证控件上的文本        int dx = 20;        for (int i = 0; i < 4; i++) {            canvas.drawText("" + mCheckNum[i], dx, getHeight() / 2 + getPositon(mBound.height() / 2), mPaint);            dx += (getWidth() / 2 - mBound.width() / 2) + i / 5 + 20;        }//      canvas.drawText(mTitleText, getWidth() / 2 - mBound.width() / 2, getHeight() / 2 + mBound.height() / 2, mPaint);    }    //计算验证码的绘制y点位置    private int getPositon(int height) {        int tempPositoin = (int) (Math.random() * height);        if (tempPositoin < 20) {            tempPositoin += 20;        }        return tempPositoin;    }    // 随机产生点的圆心点坐标    public static int[] getPoint(int height, int width) {        int[] tempCheckNum = {0, 0, 0, 0};        tempCheckNum[0] = (int) (Math.random() * width);        tempCheckNum[1] = (int) (Math.random() * height);        return tempCheckNum;    }    //随机产生划线的起始点坐标和结束点坐标    public static int[] getLine(int height, int width) {        int[] tempCheckNum = {0, 0, 0, 0};        for (int i = 0; i < 4; i += 2) {            tempCheckNum[i] = (int) (Math.random() * width);            tempCheckNum[i + 1] = (int) (Math.random() * height);        }        return tempCheckNum;    }}
2.MainActivity:

package com.example.yanzhengma;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;public class MainActivity extends AppCompatActivity implements View.OnClickListener {    private AuthCodeView mAuthCodeView;    private Button mButton;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();    }    private void initView() {        mAuthCodeView = (AuthCodeView) findViewById(R.id.AuthCodeView);        mButton = (Button) findViewById(R.id.button);        mButton.setOnClickListener(this);    }    @Override    public void onClick(View view) {        switch (view.getId()) {            case R.id.button:                EditText editText = (EditText) findViewById(R.id.editText);                String codeString = editText.getText().toString().trim();                if (codeString.equals(mAuthCodeView.getAuthCode())) {                    Toast.makeText(this, "恭喜你,验证码验证正确!", Toast.LENGTH_LONG).show();                } else {                    Toast.makeText(this, "验证码错误!", Toast.LENGTH_LONG).show();                }                break;        }    }}
3.activity_main:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    xmlns:authcodeview="http://schemas.android.com/apk/res-auto"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    >    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="horizontal">        <com.example.yanzhengma.AuthCodeView            android:id="@+id/AuthCodeView"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:padding="10dp"            android:layout_gravity="center"            authcodeview:titleText="3712"            authcodeview:titleTextColor="#ff0"            authcodeview:titleTextSize="40sp"            />        <TextView            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_gravity="center"            android:text="点击验证码,换一张" />    </LinearLayout><LinearLayout    android:layout_width="match_parent"    android:layout_height="wrap_content">    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="输入验证码:" />    <EditText        android:id="@+id/editText"        android:layout_width="match_parent"        android:layout_height="wrap_content" /></LinearLayout>    <Button        android:id="@+id/button"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="验证"/></LinearLayout>