Android 自定义密码输入框

作者: cgrass | 来源:发表于2018-03-08 23:47 被阅读458次

    效果

    自定义密码输入框,项目的一个界面需求,我把这个自定义的输入框提取出来作为这次内容的题目。
    输入前:


    image.png

    输入后:


    image.png

    输入1个字符就红一个圈圈,很简单的效果。

    思路

    1.自定义EditText。
    2.背景为一个外圆环加内实心圆。
    3.edittext的长度变化时候重新绘制背景或者红色环位置。

    关键代码

    代码其实也很简单,顺手拿资源的请到文末。

    1.画背景

      /**
         * 绘制背景外圆
         */
        private void drawOutRing(Canvas canvas) {
            mPaint.setColor(mBgColor);
            // 设置画笔为空心
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(mBgSize);
            RectF rectF = new RectF(mBgSize, mBgSize, getWidth() - mBgSize, getHeight() - mBgSize);
            // 画圆
            for (int i = 0; i < mPasswordNumber; i++) {
                int cx = i * mDivisionLineSize + i * mPasswordItemWidth + mPasswordItemWidth / 2 + mBgSize;
                canvas.drawCircle(cx, getHeight() / 2, mOutRadius, mPaint);
            }
    
        }
    

    2.画实心内圆背景

       /**
         * 绘制背景内圆
         */
        private void drawInRing(Canvas canvas) {
            mPaint.setColor(mDivisionLineColor);
            // 设置画笔为实心
            mPaint.setStyle(Paint.Style.FILL);
            // 画圈圈
            for (int i = 0; i < mPasswordNumber; i++) {
                int cx = i * mDivisionLineSize + i * mPasswordItemWidth + mPasswordItemWidth / 2 + mBgSize;
                canvas.drawCircle(cx, getHeight() / 2, mPasswordRadius, mPaint);
            }
        }
    }
    

    3.绘制输入密码的变化动作

    /**
         * 绘制隐藏的密码
         */
        private void drawHidePassword(Canvas canvas) {
            int passwordLength = getText().length();
            if (passwordLength > 6) passwordLength = 6;
            mPaint.setColor(mPasswordColor);
            // 画实心内圆
            mPaint.setStyle(Paint.Style.FILL);
            for (int i = 0; i < passwordLength; i++) {
                int cx = i * mDivisionLineSize + i * mPasswordItemWidth + mPasswordItemWidth / 2 + mBgSize;
                canvas.drawCircle(cx, getHeight() / 2, mPasswordRadius, mPaint);
            }
            //外圆颜色
            mPaint.setColor(mPasswordColor);
            // 设置画笔为空心
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(mBgSize);
            RectF rectF = new RectF(mBgSize, mBgSize, getWidth() - mBgSize, getHeight() - mBgSize);
            // 画空心外圆
            for (int i = 0; i < passwordLength; i++) {
                int cx = i * mDivisionLineSize + i * mPasswordItemWidth + mPasswordItemWidth / 2 + mBgSize;
                canvas.drawCircle(cx, getHeight() / 2, mOutRadius, mPaint);
            }
    
        }
    

    4.重写onDraw

       int passwordWidth = getWidth() - (mPasswordNumber - 1) * mDivisionLineSize;
            mPasswordItemWidth = passwordWidth / mPasswordNumber;
            // 绘制背景外圆
            drawOutRing(canvas);
            // 绘制背景内圆
            drawInRing(canvas);
            // 绘制密码
            drawHidePassword(canvas);
    

    5.xml引用

     <com***.PasswordView
            android:id="@+id/password"
            android:layout_width="240dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginTop="10dp"
            android:background="@null">
        </com***.PasswordView>
    

    6.还可以设置些属性
    在sytle中设置,通过xml中的app:xxx引用。

     <com.*.PasswordView
            android:id="@+id/password"
            android:layout_width="240dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginTop="10dp"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            app:bgColor="#ffffff"
            android:background="@null">
        </com.*.PasswordView>
    

    完整代码

    一些样式,我设置了,结果直接没用上

        <declare-styleable name="PasswordView">
            <!-- 密码的个数 -->
            <attr name="passwordNumber" format="integer"/>
            <!-- 密码圆点的半径 -->
            <attr name="passwordRadius" format="dimension"/>
            <!-- 密码圆点的颜色 -->
            <attr name="passwordColor" format="color"/>
            <!-- 外圈颜色 -->
            <attr name="outRingColor" format="color"/>
            <!-- 外圆线条大小 -->
            <attr name="outRingLineSize" format="color"/>
            <!-- 背景边框的颜色 -->
            <attr name="bgColor" format="color"/>
            <!-- 背景边框的大小 -->
            <attr name="bgSize" format="dimension"/>
            <!-- 背景边框的圆角大小 -->
            <attr name="bgCorner" format="dimension"/>
        </declare-styleable>
    

    自定义Edittext

    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.RectF;
    import android.util.AttributeSet;
    import android.util.TypedValue;
    import android.view.inputmethod.EditorInfo;
    import android.widget.EditText;
    /**
     *自定义密码输入框
     */
    
    public class PasswordView extends EditText {
        // 画笔
        private Paint mPaint;
        // 一个密码所占的宽度
        private int mPasswordItemWidth;
        // 密码的个数默认为6位数
        private int mPasswordNumber = 6;
        // 背景圆颜色
        private int mBgColor = Color.parseColor("#d1d2d6");
        // 背景大小
        private int mBgSize = 1;
        // 背景边框圆角大小
        private int mBgCorner = 0;
        // 外圆的颜色
        private int outRingLineColor = mBgColor;
        // 外圆线条的大小
        private int outRingLineSize = 1;
        // 密码输入的颜色
        private int mPasswordColor = Color.parseColor("#cb3435");
         // 密码圆点的半径大小
        private int mPasswordRadius = 6;
        // 外圆半径大小
        private int mOutRadius = 25;
        public PasswordView(Context context) {
            this(context, null);
        }
    
        public PasswordView(Context context, AttributeSet attrs) {
            super(context, attrs);
            initPaint();
            initAttributeSet(context, attrs);
            // 设置输入模式是密码
            setInputType(EditorInfo.TYPE_TEXT_VARIATION_PASSWORD);
            // 不显示光标
            setCursorVisible(false);
        }
    
        /**
         * 初始化属性
         */
        private void initAttributeSet(Context context, AttributeSet attrs) {
            TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.PasswordView);
            // 获取大小
            outRingLineSize = (int) array.getDimension(R.styleable.PasswordView_outRingLineSize, dip2px(outRingLineSize));
            mPasswordRadius = (int) array.getDimension(R.styleable.PasswordView_passwordRadius, dip2px(mPasswordRadius));
            mBgSize = (int) array.getDimension(R.styleable.PasswordView_bgSize, dip2px(mBgSize));
            mBgCorner = (int) array.getDimension(R.styleable.PasswordView_bgCorner, 0);
            // 获取颜色
            mBgColor = array.getColor(R.styleable.PasswordView_bgColor, mBgColor);
            outRingLineColor = array.getColor(R.styleable.PasswordView_outRingColor, outRingLineColor);
            mPasswordColor = array.getColor(R.styleable.PasswordView_passwordColor, mPasswordColor);
            array.recycle();
        }
    
        /**
         * 初始化画笔
         */
        private void initPaint() {
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setDither(true);
        }
    
        /**
         * dip 转 px
         */
        private int dip2px(int dip) {
            return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                    dip, getResources().getDisplayMetrics());
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            int passwordWidth = getWidth() - (mPasswordNumber - 1) * outRingLineSize;
            mPasswordItemWidth = passwordWidth / mPasswordNumber;
            // 绘制背景外圆
            drawOutRing(canvas);
            // 绘制背景内圆
            drawInRing(canvas);
            // 绘制密码
            drawHidePassword(canvas);
        }
    
        @Override
        public void setText(CharSequence text, BufferType type) {
            super.setText(text, type);
        }
        /**
         * 绘制背景外圆
         */
        private void drawOutRing(Canvas canvas) {
            mPaint.setColor(mBgColor);
            // 设置画笔为空心
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(mBgSize);
            RectF rectF = new RectF(mBgSize, mBgSize, getWidth() - mBgSize, getHeight() - mBgSize);
            // 画圆
            for (int i = 0; i < mPasswordNumber; i++) {
                int cx = i * outRingLineSize + i * mPasswordItemWidth + mPasswordItemWidth / 2 + mBgSize;
                canvas.drawCircle(cx, getHeight() / 2, mOutRadius, mPaint);
            }
    
        }
    
        /**
         * 绘制隐藏的密码
         */
        private void drawHidePassword(Canvas canvas) {
            int passwordLength = getText().length();
            if (passwordLength > 6) passwordLength = 6;
            mPaint.setColor(mPasswordColor);
            // 设置画笔为实心
            mPaint.setStyle(Paint.Style.FILL);
            for (int i = 0; i < passwordLength; i++) {
                int cx = i * outRingLineSize + i * mPasswordItemWidth + mPasswordItemWidth / 2 + mBgSize;
                canvas.drawCircle(cx, getHeight() / 2, mPasswordRadius, mPaint);
            }
            //外圆
            mPaint.setColor(mPasswordColor);
            // 设置画笔为空心
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(mBgSize);
            RectF rectF = new RectF(mBgSize, mBgSize, getWidth() - mBgSize, getHeight() - mBgSize);
            // 如果没有设置圆角,就画矩形
            for (int i = 0; i < passwordLength; i++) {
                int cx = i * outRingLineSize + i * mPasswordItemWidth + mPasswordItemWidth / 2 + mBgSize;
                canvas.drawCircle(cx, getHeight() / 2, mOutRadius, mPaint);
            }
    
        }
    
        /**
         * 绘制背景内圆
         */
        private void drawInRing(Canvas canvas) {
            mPaint.setColor(outRingLineColor);
            // 设置画笔为实心
            mPaint.setStyle(Paint.Style.FILL);
            // 画圈圈
            for (int i = 0; i < mPasswordNumber; i++) {
                int cx = i * outRingLineSize + i * mPasswordItemWidth + mPasswordItemWidth / 2 + mBgSize;
                canvas.drawCircle(cx, getHeight() / 2, mPasswordRadius, mPaint);
            }
        }
    }
    

    结束

    有事请留言。

    相关文章

      网友评论

      本文标题:Android 自定义密码输入框

      本文链接:https://www.haomeiwen.com/subject/kgqefftx.html