自定义密码输入框(1字符1边框)

自定义密码输入框

效果图

自定义密码输入框(1字符1边框)_第1张图片
自定义密码输入框(1字符1边框)_第2张图片

PasswordEditText
public class PasswordEditText extends AppCompatEditText {

    private Paint borderPaint;
    private Paint bgPaint;

    private float borderWidth;
    private float borderRadius;

    private int passwordLength;//密码长度==文本输入长度
    private int measuredHeight;

    private float averageWidth;//单个密码框宽度

    private RectF bgRectF;
    private RectF textRectF;

    private int textLength;//输入文本长度
    private CharSequence text;//输入的文本

    private boolean isPasswordVisible;//是否明文显示
    private String passwordReplaceText;//密文替代字符 isPasswordVisible= true可用
    private int borderSpace;//密码框间距 为0 外边框为整体单个密码框使用线条分割  不为0 单个密码框都有边框
    private OnInputCompletedListener completedListener;


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

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

    public PasswordEditText(final Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.PasswordEditText);
        borderWidth = typedArray.getDimensionPixelSize(R.styleable.PasswordEditText_borderWidth, 1);
        int borderColor = typedArray.getColor(R.styleable.PasswordEditText_borderColor, Color.BLACK);
        borderRadius = typedArray.getDimensionPixelSize(R.styleable.PasswordEditText_borderRadius, BaseUtils.dip2px(2));
        borderSpace = typedArray.getDimensionPixelSize(R.styleable.PasswordEditText_borderSpace, 0);
        int color = typedArray.getColor(R.styleable.PasswordEditText_android_background, Color.TRANSPARENT);
        passwordLength = typedArray.getInt(R.styleable.PasswordEditText_android_maxLength, 6);
        isPasswordVisible = typedArray.getBoolean(R.styleable.PasswordEditText_passwordVisible, true);
        String s = typedArray.getString(R.styleable.PasswordEditText_passwordReplaceText);
        passwordReplaceText = TextUtils.isEmpty(s) ? "*" : s;
        typedArray.recycle();

        setSingleLine();
        setBackground(null);
        super.setBackgroundColor(Color.TRANSPARENT);

        borderPaint = new Paint();
        borderPaint.setAntiAlias(false);
        borderPaint.setStyle(Paint.Style.STROKE);
        borderPaint.setStrokeWidth(borderWidth);
        borderPaint.setColor(borderColor);

        bgPaint = new Paint();
        bgPaint.setAntiAlias(false);
        bgPaint.setColor(color);
        bgPaint.setStrokeWidth(2);

        bgRectF = new RectF();
        textRectF = new RectF();
    }

    public void setBorderColor(@ColorInt int color) {
        if (borderPaint != null) {
            borderPaint.setColor(color);
            invalidate();
        }
    }

    public void setBorderWidth(int dp) {
        if (borderPaint != null) {
            borderWidth = BaseUtils.dip2px(dp);
            borderPaint.setStrokeWidth(borderWidth);
            invalidate();
        }
    }

    public void setBorderRadius(int dp) {
        borderRadius = BaseUtils.dip2px(dp);
        invalidate();
    }

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

    public void setPasswordVisible(boolean isVisible) {
        isPasswordVisible = isVisible;
        invalidate();
    }

    public void setPasswordReplaceText(String s) {
        if (!TextUtils.isEmpty(s)) {
            passwordReplaceText = s;
            invalidate();
        }
    }

    public int getPasswordLength() {
        return passwordLength;
    }

    public int getTextLength() {
        return textLength;
    }

    @Override
    public void setBackgroundColor(@ColorInt int color) {
        if (bgPaint != null) {
            bgPaint.setColor(color);
            invalidate();
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        int measuredWidth = getMeasuredWidth();
        measuredHeight = getMeasuredHeight();
        bgRectF = new RectF(0, 0, measuredWidth, measuredHeight);
        averageWidth = (measuredWidth - (passwordLength - 1) * borderSpace) / (passwordLength * 1f);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        drawBorder(canvas);
        drawText(canvas);
    }

    /**
     * 绘制密码
     */
    private void drawText(Canvas canvas) {
        for (int i = 0; i < textLength; i++) {
            if (textRectF == null) {
                return;
            }
            initTextRectF(i);
            TextPaint paint = getPaint();
            paint.setTextAlign(Paint.Align.CENTER);
            Paint.FontMetrics fontMetrics = paint.getFontMetrics();
            if (fontMetrics != null && textRectF != null) {
                float dy = (fontMetrics.descent - fontMetrics.ascent) / 2 - fontMetrics.descent;
                int baseYLine = (int) (textRectF.centerY() + dy);
                String s = isPasswordVisible ? String.valueOf(text.charAt(i)) : passwordReplaceText;
                canvas.drawText(s, textRectF.centerX(), baseYLine, paint);
            }
        }
    }

    private void initTextRectF(int i) {
        float startX = (averageWidth + borderSpace) * i + borderWidth / 2f;
        float stopX = averageWidth + startX - borderWidth;
        textRectF.set(startX, borderWidth / 2f, stopX, measuredHeight - borderWidth / 2f);
    }

    /**
     * 绘制边框
     */
    private void drawBorder(Canvas canvas) {
        if (borderSpace == 0) {
            drawBg(canvas, bgRectF);
            for (int i = 1; i < passwordLength; i++) {
                float startX = averageWidth * i;
                canvas.drawLine(startX, bgRectF.top, startX, measuredHeight, borderPaint);
            }
        } else {
            for (int i = 0; i < passwordLength; i++) {
                initTextRectF(i);
                drawBg(canvas, textRectF);
            }
        }
    }

    private void drawBg(Canvas canvas, RectF bgRectF) {
        canvas.drawRoundRect(bgRectF, borderRadius, borderRadius, bgPaint);
        canvas.drawRoundRect(bgRectF, borderRadius, borderRadius, borderPaint);
    }

    @Override
    protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
        this.text = text;
        super.onTextChanged(text, start, lengthBefore, lengthAfter);
        if (text != null) {
            this.textLength = text.toString().length();
            invalidate();
            if (textLength >= passwordLength && completedListener != null) {
                completedListener.onComplete(text.toString(), null);
            }
        }
    }

    public void setOnInputCompletedListener(OnInputCompletedListener completedListener) {
        this.completedListener = completedListener;
    }
}
attrs.xml
 
        
        
        
        
        
        
        
        
    
OnInputCompletedListener
public interface OnInputCompletedListener {
    void onComplete(String value, OnCheckResultCallback callback);
}

OnCheckResultCallback
public interface OnCheckResultCallback {
    void onCheckedResult(boolean result);
}

密码键盘:https://blog.csdn.net/TomCat0916/article/details/105751838
仿支付宝密码输入弹窗https://blog.csdn.net/TomCat0916/article/details/105776871

你可能感兴趣的:(自定义控件,android,自定义密码输入框)