美文网首页
仿支付宝支付密码输入框

仿支付宝支付密码输入框

作者: 猫KK | 来源:发表于2018-08-07 23:41 被阅读0次

    今天我们要实现的效果如下,支付宝的支付密码输入框


    WechatIMG265.jpeg

    分析

    使用系统的输入框很明显不能实现这样的效果,所以自定义view 来实现
    我们需要自己绘制圆角矩形框,中间分割线,和密码的小圆点。

    实现

    我们选用继承EditText,至于为什么继承这个,主要是为了能轻松实现
    首先我们重写onDraw()方法

     @Override
        protected void onDraw(Canvas canvas) {
            //绘制背景
            drawBg(canvas);
            //绘制分割线
            drawDivision(canvas);
            //绘制圆点密码
            drawPassword(canvas);
        }
    
        
        /**
         * 绘制背景
         *
         * @param canvas
         */
        private void drawBg(Canvas canvas) {
            //获取矩形的大小
            RectF rectF = new RectF(0, 0, getMeasuredWidth(), getMeasuredHeight());
            //设置颜色、空心、背景框线的大小
            mPaint.setColor(mBgColor);
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(mBgWidth);
            //直接绘制圆角矩形
            canvas.drawRoundRect(rectF, mBgRadius, mBgRadius, mPaint);
        }
    
    
        /**
         * 绘制分割线
         *
         * @param canvas
         */
        private void drawDivision(Canvas canvas) {
            //计算每一个密码框的长度
            int itemWith = (getMeasuredWidth() - (2 * mBgWidth)) / mPasswordCount;
            mPaint.setColor(mDivisionColor);
            mPaint.setStrokeWidth(mDivisionWith);
            //循环,需要绘制的分割线
            for (int i = 0; i < mPasswordCount - 1; i++) {
                float startX = mBgWidth + (itemWith * (i + 1));
                float startY = 0;
                float endY = startY + getMeasuredHeight();
                canvas.drawLine(startX, startY, startX, endY, mPaint);
            }
        }
    
    
        /**
         * 绘制圆点密码
         *
         * @param canvas
         */
        private void drawPassword(Canvas canvas) {
             //计算每一个密码框的长度
            int itemWith = (getMeasuredWidth() - (2 * mBgWidth)) / mPasswordCount;
            mPaint.setColor(mPasswordColor);
            mPaint.setStrokeWidth(mPasswordSize);
            mPaint.setStyle(Paint.Style.FILL);
             //这就是为什么要继承至EditText 可以直接获取文本内容
            String text = getText().toString().trim();
            //获取内容,循环绘制小圆点
            if (!TextUtils.isEmpty(text)) {
                for (int i = 0; i < text.length(); i++) {
                    float cx = mBgWidth + (itemWith / 2) + itemWith * i;
                    float cy = getMeasuredHeight() / 2;
                    canvas.drawCircle(cx, cy, mPasswordSize, mPaint);
                }
            }
        }
    

    核心代码就为上面这些,还有其他的获取颜色、大小的设置,我就不一一列举了

    完整代码

    
    /**
     * 自定义密码输入框
     */
    public class KeyWordView extends AppCompatEditText implements TextWatcher {
    
        private int mDefaultBgColor = Color.parseColor("#666666");
        private int mDefaultBgWith = 5;
        private int mDefaultPasswordCount = 4;
        private int mDefaultDivisionColor = Color.parseColor("#666666");
        private int mDefaultDivisionWith = 5;
        private int mDefaultPasswordColor = Color.parseColor("#666666");
        private int mDefaultPasswrdSize = 18;
    
        //背景框的圆角
        private int mBgRadius;
        //画笔
        private Paint mPaint;
        //背景框颜色
        private int mBgColor;
        //背景框线的宽度
        private int mBgWidth;
        //总密码的个数
        private int mPasswordCount;
        //分割线的颜色
        private int mDivisionColor;
        //分割线的宽度
        private int mDivisionWith;
        //密码圆点的颜色
        private int mPasswordColor;
        //密码圆点的大小
        private int mPasswordSize;
    
        public KeyWordView(Context context) {
            super(context);
            init();
        }
    
        public KeyWordView(Context context, AttributeSet attrs) {
            super(context, attrs);
            initAttr(context, attrs);
            init();
        }
    
        public KeyWordView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            initAttr(context, attrs);
            init();
        }
    
        /**
         * 初始化xml 设置的属性
         *
         * @param context
         * @param attrs
         */
        private void initAttr(Context context, AttributeSet attrs) {
            if (attrs != null) {
                TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.KeyWordView);
                mBgWidth = (int) typedArray.getDimension(R.styleable.KeyWordView_bg_width, mDefaultBgWith);
                mBgColor = typedArray.getColor(R.styleable.KeyWordView_bg_color, mDefaultBgColor);
                mPasswordCount = typedArray.getInteger(R.styleable.KeyWordView_password_count, mDefaultPasswordCount);
                mDivisionColor = typedArray.getColor(R.styleable.KeyWordView_division_color, mDefaultDivisionColor);
                mDivisionWith = (int) typedArray.getDimension(R.styleable.KeyWordView_division_width, mDefaultDivisionWith);
                mPasswordColor = typedArray.getColor(R.styleable.KeyWordView_password_color, mDefaultPasswordColor);
                mPasswordSize = (int) typedArray.getDimension(R.styleable.KeyWordView_password_size, mDefaultPasswrdSize);
                mBgRadius = (int) typedArray.getDimension(R.styleable.KeyWordView_bg_radius, 0);
                typedArray.recycle();
            }
        }
    
        /**
         * 初始化画笔
         */
        private void init() {
            mPaint = new Paint();
            //抗锯齿
            mPaint.setAntiAlias(true);
            //防抖动
            mPaint.setDither(true);
            //设置输入最大长度
            setFilters(new InputFilter[]{new InputFilter.LengthFilter(mPasswordCount)});
            //设置只能输入数字
            setInputType(InputType.TYPE_CLASS_NUMBER);
            //监听文本变化,回调
            addTextChangedListener(this);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            //绘制背景
            drawBg(canvas);
            //绘制分割线
            drawDivision(canvas);
            //绘制圆点密码
            drawPassword(canvas);
        }
    
        /**
         * 绘制圆点密码
         *
         * @param canvas
         */
        private void drawPassword(Canvas canvas) {
            //一个格子的长度
            int itemWith = (getMeasuredWidth() - (2 * mBgWidth)) / mPasswordCount;
            mPaint.setColor(mPasswordColor);
            mPaint.setStrokeWidth(mPasswordSize);
            mPaint.setStyle(Paint.Style.FILL);
            String text = getText().toString().trim();
            if (!TextUtils.isEmpty(text)) {
                for (int i = 0; i < text.length(); i++) {
                    float cx = mBgWidth + (itemWith / 2) + itemWith * i;
                    float cy = getMeasuredHeight() / 2;
                    canvas.drawCircle(cx, cy, mPasswordSize, mPaint);
                }
            }
        }
    
        /**
         * 绘制分割线
         *
         * @param canvas
         */
        private void drawDivision(Canvas canvas) {
            int itemWith = (getMeasuredWidth() - (2 * mBgWidth)) / mPasswordCount;
            mPaint.setColor(mDivisionColor);
            mPaint.setStrokeWidth(mDivisionWith);
            for (int i = 0; i < mPasswordCount - 1; i++) {
                float startX = mBgWidth + (itemWith * (i + 1));
                float startY = 0;
                float endY = startY + getMeasuredHeight();
                canvas.drawLine(startX, startY, startX, endY, mPaint);
            }
        }
    
        /**
         * 绘制背景
         *
         * @param canvas
         */
        private void drawBg(Canvas canvas) {
            RectF rectF = new RectF(0, 0, getMeasuredWidth(), getMeasuredHeight());
            mPaint.setColor(mBgColor);
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(mBgWidth);
            canvas.drawRoundRect(rectF, mBgRadius, mBgRadius, mPaint);
        }
    
        @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) {
            //当输入密码为最长的时候 回调
            if (!TextUtils.isEmpty(s) && s.length() == mPasswordCount && this.listener != null) {
                this.listener.full(s.toString().trim());
            }
        }
    
        private IPasswordFullListener listener;
    
        public void setPasswordFullListener(IPasswordFullListener listener) {
            this.listener = listener;
        }
    
        public interface IPasswordFullListener {
            void full(String password);
        }
    }
    
    //自定义的属性
    <declare-styleable name="KeyWordView">
            <attr name="bg_width" format="dimension" />
            <attr name="bg_color" format="color" />
            <attr name="password_count" format="integer" />
            <attr name="division_color" format="color" />
            <attr name="division_width" format="dimension" />
            <attr name="password_color" format="color" />
            <attr name="password_size" format="dimension" />
            <attr name="bg_radius" format="dimension" />
        </declare-styleable>
    
    

    相关文章

      网友评论

          本文标题:仿支付宝支付密码输入框

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