自定义验证码校验对话框

样式图:


自定义dialog的布局文件layout_code_dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="180dp"
    android:layout_height="90dp"
    android:layout_gravity="center"
    android:background="@drawable/code_view_bg_shape"
    android:orientation="vertical"
    android:paddingTop="5dp">

    <EditText
        android:cursorVisible="false"
        android:id="@+id/edt_code_input"
        android:layout_width="80dp"
        android:gravity="center"
        android:layout_height="40dp"
        android:layout_marginTop="2dp"
        android:layout_marginLeft="10dp"
        android:background="@drawable/code_view_input_bg_shape"
        />

    <mchenys.net.csdn.blog.pcbaby_v8_testdemo.view.CodeView
        android:id="@+id/code_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/edt_code_input"
        android:layout_marginLeft="10dp"
        android:layout_marginBottom="5dp"
        android:layout_marginRight="5dp"
        android:layout_toRightOf="@+id/edt_code_input" />

    <TextView
        android:id="@+id/tv_info"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/code_view"
        android:layout_below="@+id/code_view"
        android:text="点击图片更换"
        android:textSize="10sp" />

    <View
        android:id="@+id/view_line"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_below="@+id/edt_code_input"
        android:layout_marginTop="5dp"
        android:background="#66666666" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/view_line">

        <Button
            android:id="@+id/btn_cancle"
            android:textSize="15sp"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@android:color/transparent"
            android:gravity="center"
            android:text="取消" />

        <View
            android:layout_width="1dp"
            android:layout_height="match_parent"
            android:background="#66666666" />

        <Button
            android:id="@+id/btn_sure"
            android:textSize="15sp"
            android:textColor="#029AFF"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@android:color/transparent"
            android:gravity="center"
            android:text="确定" />
    </LinearLayout>
</RelativeLayout>

其中背景图片code_view_bg_shape和code_view_input_bg_shape是/drawable目录下创建的shape的xml文件.

分别为:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#fff" />
    <corners android:radius="10dp" />
</shape>


<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <stroke
        android:width="1dp"
        android:color="#66666666"
        />
</shape>

mchenys.net.csdn.blog.pcbaby_v8_testdemo.view.CodeView是一个自定义的验证码控件,代码如下:

package mchenys.net.csdn.blog.pcbaby_v8_testdemo.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.View;

import java.util.Random;

/**
 * Created by mChenys on 2015/12/1.
 */
public class CodeView extends View implements View.OnClickListener {
    private static final char[] CHARS = {
            '2', '3', '4', '5', '6', '7', '8', '9',
            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'l', 'm',
            'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
            'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
    };
    //variables
    private String code;
    private Random random = new Random();
    private int codeLength;//个数
    private float fontSize;//字体大小
    private Paint mTextPaint;//字体的画笔
    private int paddingLeft;//左内边距
    private int paddingTop;//上内边距

    public void setCodeLength(int codeLength) {
        this.codeLength = codeLength;
    }

    public String getCode() {
        return code;
    }

    public CodeView(Context context) {
        this(context, null);
    }

    public CodeView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CodeView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        codeLength = 4;
        paddingLeft = dp2px(8);
        paddingTop = dp2px(5);
        mTextPaint = new Paint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setStyle(Paint.Style.FILL);
        mTextPaint.setTextSize(25);
        mTextPaint.setColor(Color.BLACK);
        mTextPaint.setTypeface(Typeface.DEFAULT_BOLD);
        fontSize = mTextPaint.getTextSize();//字体大小
        System.out.println("fontSize px:" + fontSize);
        mTextPaint.setTextAlign(Paint.Align.CENTER);//字体居中
        code = createCode();//初始化的时候先生存code值,否则调用getCode()方法返回将是null
        //设置点击监听
        setOnClickListener(this);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //左右边距+字体的字间距(这里字间距用fontSize代替)
        int width = (int) (2 * paddingLeft + (codeLength - 1) * fontSize);
        //上下边距+字体的高度
        int height = (int) (2 * paddingTop + fontSize);
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(Color.parseColor("#F2F2F2"));
        System.out.println("onDraw code is :" + code);
        char[] codeChar = code.toCharArray();
        int fontX = 0; //每个字的X坐标
        for (int i = 0; i < codeChar.length; i++) {
            fontX = (int) (paddingLeft + i * fontSize);
            String text = codeChar[i] + "";
            canvas.drawText(text, fontX, paddingTop + fontSize, mTextPaint);
        }
    }

    private String createCode() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < codeLength; i++) {
            sb.append(CHARS[random.nextInt(CHARS.length)]);
        }
        return sb.toString();
    }

    /**
     * dp转px
     *
     * @param dp
     * @return
     */
    private int dp2px(float dp) {
        float density = getContext().getResources().getDisplayMetrics().density;
        return (int) (dp * density + 0.5f);
    }

    /**
     * sp to px
     */
    public int sp2px(float sp) {
        float fontScale = getContext().getResources().getDisplayMetrics().scaledDensity;
        return (int) (sp * fontScale + 0.5f);
    }

    //点击回调方法里面处理验证码的更新
    @Override
    public void onClick(View v) {
        code = createCode();//重新生成新的验证码
        invalidate(); //刷新界面UI,会调用onDraw方法
        if (null != listener) {
            listener.OnChange(getCode());//通过自定义的监听接口返回新的验证码给调用者
        }
    }

    //验证码变化的监听器
    public interface OnCodeChangeListener {
        void OnChange(String code);
    }

    private OnCodeChangeListener listener;

    public void setOnCodeChangeListener(OnCodeChangeListener listener) {
        this.listener = listener;
    }
}

使用例子如下:

/**
 * Created by mChenys on 2015/11/30.
 */
public class TextActivity extends Activity {
    private String inputCode; //用户输入的验证码值
    private String verificationCode;//图片显示的验证码值

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_text);
    }

    public void showCodeView(View view) {
        final Dialog dialog = new Dialog(TextActivity.this, R.style.myDialog);
        dialog.setContentView(R.layout.layout_code_dialog);
        //提示信息
        final TextView tvInfo = (TextView) dialog.findViewById(R.id.tv_info);
        CodeView codeView = (CodeView) dialog.findViewById(R.id.code_view);
        final EditText edtInput = (EditText) dialog.findViewById(R.id.edt_code_input);
        //用户输入的验证码
        inputCode = edtInput.getText().toString().trim();
        //验证码图片显示的code
        verificationCode = codeView.getCode();
        codeView.setOnCodeChangeListener(new CodeView.OnCodeChangeListener() {
            @Override
            public void OnChange(String code) {
                //点击验证码图片需要更新code值
                verificationCode = code;
            }
        });
        //确定按钮
        dialog.findViewById(R.id.btn_sure).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                inputCode = edtInput.getText().toString().trim();
                //校验验证码
                if (TextUtils.isEmpty(inputCode)) {
                    tvInfo.setText("请输入验证码!");
                } else if (!verificationCode.equalsIgnoreCase(inputCode)) {
                    tvInfo.setText("验证码错误");
                } else {
                    //校验成功
                    dialog.dismiss();
                }
            }
        });
        //取消按钮
        dialog.findViewById(R.id.btn_cancle).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });
        dialog.setCanceledOnTouchOutside(false);
        dialog.show();
    }
}

其中TextActivity的布局文件就是一个button,设置onClick="showCodeView"的属性:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#0f0"
    android:padding="20dp">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:onClick="showCodeView" />
</RelativeLayout>

输入验证的码提示的2种状态:

1.未输入的情况下,点击确定,提示"请输入验证码!"



2.输入错误,提示"验证码错误"

自定义验证码校验对话框_第1张图片

你可能感兴趣的:(自定义验证码校验对话框)