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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34942689/article/details/88743215

自定义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>

猜你喜欢

转载自blog.csdn.net/qq_34942689/article/details/88743215