Android自定义view三验证码输入控件

博客主要围绕自定义输入六位验证码的控件展开,给出了部分代码示例,包括根据输入情况设置边框颜色、绘制路径,以及绘制密码文本等内容,还提及了attrs文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自定义view三:输入六位验证码的控件

public class InputCodeView extends AppCompatEditText {
private int   currentColor = 0xFFCCCCCC;
private int   borderColor  = 0xFFCCCCCC;
private float borderWidth  = 5;
private float borderRadius = 3;
private int   passwordLength = 6;
private int   passwordColor  = 0xFFCCCCCC;
private float passwordWidth  = 8;
private float passwordRadius = 3;
private Paint passwordPaint = new Paint();
private Paint borderPaint   = new Paint();
private int    textLength;
private String textContent;
private float   splitLineWidth    = 0; //分割宽度
private float   eachPasswordWidth = 0;  //每个方块的宽度
private Path    mPath             = new Path();
private boolean passwordBold      = false;
private String curPassword;

public InputCodeView(Context context, AttributeSet attrs) {
    super(context, attrs);

    DisplayMetrics dm = getResources().getDisplayMetrics();
    borderWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, borderWidth, dm);
    borderRadius = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, borderRadius, dm);
    passwordLength = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, passwordLength, dm);
    passwordWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, passwordWidth, dm);
    passwordRadius = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, passwordRadius, dm);
    splitLineWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, splitLineWidth, dm);

    TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.InputCodeView, 0, 0);
    currentColor = a.getColor(R.styleable.InputCodeView_pivCurrentColor, borderColor);
    borderColor = a.getColor(R.styleable.InputCodeView_pivBorderColor, borderColor);
    borderWidth = a.getDimension(R.styleable.InputCodeView_pivBorderWidth, borderWidth);
    borderRadius = a.getDimension(R.styleable.InputCodeView_pivBorderRadius, borderRadius);
    passwordLength = a.getInt(R.styleable.InputCodeView_pivPasswordLength, passwordLength);
    passwordColor = a.getColor(R.styleable.InputCodeView_pivPasswordColor, passwordColor);
    passwordWidth = a.getDimension(R.styleable.InputCodeView_pivPasswordWidth, passwordWidth);
    passwordRadius = a.getDimension(R.styleable.InputCodeView_pivPasswordRadius, passwordRadius);
    splitLineWidth = a.getDimension(R.styleable.InputCodeView_pivSplitLineWidth, splitLineWidth);
    passwordBold = a.getBoolean(R.styleable.InputCodeView_pivPasswordBold, false);
    a.recycle();

    borderPaint.setStrokeWidth(borderWidth);
    borderPaint.setColor(borderColor);
    borderPaint.setStyle(Paint.Style.FILL);

    passwordPaint.setStrokeWidth(passwordWidth);
    passwordPaint.setTypeface(Typeface.DEFAULT);
    if (passwordBold)
        passwordPaint.setStyle(Paint.Style.STROKE);
    else passwordPaint.setStyle(Paint.Style.FILL);
    passwordPaint.setColor(passwordColor);

    addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            curPassword = s.toString();
            if (!TextUtils.isEmpty(curPassword) && passwordLength == curPassword.length()) {
                if (mOnExaminedCodeListener != null) {
                    mOnExaminedCodeListener.onExaminedCode(curPassword);
                }
            }
        }
    });
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int width_size  = MeasureSpec.getSize(widthMeasureSpec);
    int width_mode  = MeasureSpec.getMode(widthMeasureSpec);
    int height_mode = MeasureSpec.getMode(heightMeasureSpec);
    int height_size = MeasureSpec.getSize(widthMeasureSpec);
    int widthSpec   = MeasureSpec.makeMeasureSpec(width_size, width_mode);
    if (width_size / passwordLength - height_size < 20) {
        splitLineWidth = 20;
        int heightSpec = MeasureSpec.makeMeasureSpec(width_size / passwordLength - 20, MeasureSpec.EXACTLY);
        super.onMeasure(widthSpec, heightSpec);
    } else {
        super.onMeasure(widthSpec, heightMeasureSpec);
    }
}

@Override
@SuppressLint("DrawAllocation")
protected void onDraw(Canvas canvas) {
    int width  = getWidth();
    int height = getHeight();


    if (width / passwordLength - height < 20) {
        splitLineWidth = 20;
    } else {
        eachPasswordWidth = height;
        splitLineWidth = (width - passwordLength * eachPasswordWidth) / (passwordLength - 1);
    }

    eachPasswordWidth = (width - (passwordLength - 1) * splitLineWidth) / passwordLength;
    for (int i = 0; i < passwordLength; i++) {
        RectF rectIn = new RectF(i * (eachPasswordWidth + splitLineWidth) + 1, 1, (i + 1) * eachPasswordWidth + i * splitLineWidth, height);
        canvas.drawRoundRect(rectIn, borderRadius, borderRadius, borderPaint);

// if (!TextUtils.isEmpty(curPassword)) {
// if (i < curPassword.length()) borderPaint.setColor(currentColor);
// else borderPaint.setColor(borderColor);
// }
// mPath = new Path();
// mPath.moveTo(i * (eachPasswordWidth + splitLineWidth) + dp2px(6), getMeasuredHeight() - dp2px(1));
// mPath.lineTo((i + 1) * eachPasswordWidth + i * splitLineWidth - dp2px(6), getMeasuredHeight() - dp2px(1));
// canvas.drawPath(mPath, borderPaint);
}
// 密码
float cx, cy = height / 2;
passwordPaint.setColor(passwordColor);
float textSize = getTextSize();
passwordPaint.setTextSize(textSize);
passwordPaint.setAntiAlias(true);
float half = (width - (passwordLength - 1) * splitLineWidth) / passwordLength / 2;
for (int i = 0; i < textLength; i++) {
cx = i * (eachPasswordWidth + splitLineWidth) + half;
String text = textContent.substring(i, i + 1);
Rect bounds = new Rect();
passwordPaint.getTextBounds(text, 0, text.length(), bounds);
canvas.drawText(text, cx - bounds.width() / 2, cy + bounds.height() / 2, passwordPaint);
}
}

@Override
protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
    super.onTextChanged(text, start, lengthBefore, lengthAfter);
    this.textLength = text.toString().length();
    textContent = text.toString();
    invalidate();
}

public int getBorderColor() {
    return borderColor;
}

public void setBorderColor(int borderColor) {
    this.borderColor = borderColor;
    borderPaint.setColor(borderColor);
    invalidate();
}

public float getBorderWidth() {
    return borderWidth;
}

public void setBorderWidth(float borderWidth) {
    this.borderWidth = borderWidth;
    borderPaint.setStrokeWidth(borderWidth);
    invalidate();
}

public float getBorderRadius() {
    return borderRadius;
}

public void setBorderRadius(float borderRadius) {
    this.borderRadius = borderRadius;
    invalidate();
}

public int getPasswordLength() {
    return passwordLength;
}

public void setPasswordLength(int passwordLength) {
    this.passwordLength = passwordLength;
    invalidate();
}

public int getPasswordColor() {
    return passwordColor;
}

public void setPasswordColor(int passwordColor) {
    this.passwordColor = passwordColor;
    passwordPaint.setColor(passwordColor);
    invalidate();
}

public float getPasswordWidth() {
    return passwordWidth;
}

public void setPasswordWidth(float passwordWidth) {
    this.passwordWidth = passwordWidth;
    passwordPaint.setStrokeWidth(passwordWidth);
    invalidate();
}

public float getPasswordRadius() {
    return passwordRadius;
}

public void setPasswordRadius(float passwordRadius) {
    this.passwordRadius = passwordRadius;
    invalidate();
}

private int dp2px(int dp) {
    DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
    return (int) (dp * displayMetrics.density + 0.5f);
}

/**
 * 设置验证码完成回调接口
 */
public interface OnExaminedCodeListener {
    void onExaminedCode(String identified_code);
}

private OnExaminedCodeListener mOnExaminedCodeListener;

public void setOnExaminedCodeListener(OnExaminedCodeListener examinedCodeListener) {
    this.mOnExaminedCodeListener = examinedCodeListener;
}

}
attrs文件

<declare-styleable name="InputCodeView">
    <attr name="pivBorderColor" format="color" />
    <attr name="pivBorderWidth" format="dimension" />
    <attr name="pivBorderRadius" format="dimension" />
    <attr name="pivPasswordColor" format="color" />
    <attr name="pivPasswordWidth" format="dimension" />
    <attr name="pivPasswordRadius" format="dimension" />
    <attr name="pivPasswordLength" format="integer" />
    <attr name="pivSplitLineWidth" format="dimension" />
    <attr name="pivPasswordBold" format="boolean" />
    <attr name="pivCurrentColor" format="reference|color" />
</declare-styleable>
.Net 验证码控件 操作简单,使用方便参数使用有详细介绍 拖入即可应用!!!!!! 添加到工具箱的步骤 1.将 Vincent.AutoAuthCode.dll 添加到项目的 Bin文件目录下 2.右键点击 Bin 目录 选择添加引用 找到添加的 Bin文件目录下 Vincent.AutoAuthCode.dll 3.在工具栏中,右键点击 常规 选项卡 再点击 选择项 4.在弹出的对话框中的右下方 点击 浏览 找到 Bin文件目录下 Vincent.AutoAuthCode.dll 打开 点击 确定 在 工具箱 的 常规选项 看到 AutcCode 控件 直接拖到要使用验证码的页面位置 即可。 页面的点击事件会触发验证,无需后台代码验证 一、控件特点: 1、使用方便,只需要从工具栏直接拖到页面即可自动验证,零代码使用。 2、自动完成客户端以及服务器的验证码验证,Ajax验证,随用户输入即时 验证并友好提示。 3、可自定义验证码图片外观。 4、有水平方向垂直方向两种方式选择。 5、有数字、小写字母、大写字母种及任意两种组合、种组合字符选择。 6、兼容IE及FireFox。 二、使用说明。 1、属性。 IsMatch:指示用户输入验证码是否正确 TextControlWidth:文本框控件宽度 NextImgText:提示更换图片信息,该提示信息同时显示于图片上面及图片左边 IsShowNextImgText:是否在图片左边显示提示更换图片信息 EnableNextImgText:是否充许换一张图片 ErrorShowType:验证码错误显示方式 CodeStringType:验证码字符类型,组合枚举值,例如CodeStringTypes.Number|CodeStringTypes.LowerLetter CodeStringLength:验证码字符长度,最少为4 ImageType:验证码图像类型 IsMatchCase:验证码验证时是否区分大小写 LayoutDirection":控件各部分排列方向,排列的部分包括文本框、图片、"换一张图片"文本 EnableClientValidate:是否使用客户端脚本验证,验证内容包括是否为空、长度是否正确 ImageStyle:验证码图像样式 如: TextControlWidth="90px" 设置 输入验证码的文本框宽度 其中ImageStyle为复类属性,其公开属性如下: ImageStyle-ImgBgColor:图片背景色 ImageStyle-ImgNoiseColor:图片噪声颜色 ImageStyle-ImgBorderColor"图片边框颜色 ImageStyle-TextColor1:文本颜色 ImageStyle-TextColor2:文本颜色2(如果文本为单色则无效) ImageStyle-TextFontSize:文本字体大小,以像素(pix)为单位,验证码图像大小根据此而变化,如果ImgSize大于由该值指定的大小,则图像大小为ImgSize ImageStyle-ImgSize:验证码图像大小,以像素(pix)为单位,如果TextFontSize指定的大小大于该值,则图像大小为TextFontSize指定的大小 ImageStyle-Width:验证码图像大小的宽度,以像素(pix)为单位,如果TextFontSize指定的大小大于该值,则图像大小为TextFontSize指定的大小 ImageStyle-Height:验证码图像大小的高度,以像素(pix)为单位,如果TextFontSize指定的大小大于该值,则图像大小为TextFontSize指定的大小 如: ImageStyle-Width=70 设置验证码图像大小的宽度 (值必须是整数) ImageStyle-ImgBgColor=#1D3647 图片背景色 (值不要添加单、双引号 [''," "])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值