自定义View——支付密码输入框

我尽量不打错别字,用词准确,不造成阅读障碍。

本文实现支付密码输入的输入框,6个小黑点那种。

效果:

图片描述

代码:

设置自定义属性:

<declare-styleable name="PayPasswordInputView">
    <attr name="maxCount" format="integer" />
</declare-styleable>

自定义View代码:

public class PayPasswordView extends android.support.v7.widget.AppCompatEditText {
    private int circleMount = 6;             //小圆点默认数量为6个
    private RectF storkRect = new RectF();   //边框矩形

    private Paint storkPaint;          		 //边框画笔
    private Paint circlePaint;         		 //小圆点画笔
    private Paint divideLinePaint;     		 //分割线画笔

    private int divideLineStartX;
    private int height;
    private int width;
    private int textLength;

    private int startX;                //定位小圆点位置
    private int startY;                //定位小圆点位置

    private int radius = 20;

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

    public PayPasswordView(Context context, AttributeSet attrs) {
        super(context, attrs);
        getAttr(attrs);
        initPaint();
        this.setBackgroundColor(Color.TRANSPARENT);    //设置背景透明以去掉下划线
        this.setCursorVisible(false);
        this.setFilters(new InputFilter[]{new InputFilter.LengthFilter(circleMount)});
    }

    public void getAttr(AttributeSet attrs) {
        TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.PayPasswordInputView);
        circleMount = typedArray.getInteger(R.styleable.PayPasswordInputView_maxCount, circleMount);
        typedArray.recycle();
    }

    public void initPaint() {
        storkPaint = getPaint(3f, Paint.Style.STROKE, Color.GRAY);
        circlePaint = getPaint(10, Paint.Style.FILL, Color.BLACK);
        divideLinePaint = getPaint(1.5f, Paint.Style.FILL, Color.GRAY);
    }

    private Paint getPaint(float strokeWidth, Paint.Style style, int color) {
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setStrokeWidth(strokeWidth);
        paint.setStyle(style);
        paint.setAntiAlias(true);
        paint.setDither(true);
        paint.setColor(color);
        return paint;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawRoundRect(storkRect, 20, 20, storkPaint);  //画圆角矩形
        for (int i = 1; i < circleMount; i++) {
            canvas.drawLine(i * divideLineStartX, 0, i * divideLineStartX, height, divideLinePaint);
        }
        for (int i = 0; i < textLength; i++) {
            canvas.drawCircle(startX + i * 2 * startX, startY, radius, circlePaint);
        }
    }

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

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        height = h;
        width = w;
        divideLineStartX = w / circleMount;
        startX = w / circleMount / 2;
        startY = h / 2;
        storkRect.set(1.5f, 1.5f, width - 1.5f, height - 1.5f);
        //上面是画圆角矩形,如果画直角矩形设置参数为(0,0,width,height)
    }

    @Override
    protected void onSelectionChanged(int selStart, int selEnd) {
        super.onSelectionChanged(selStart, selEnd);
        if (selEnd == selStart) {
            setSelection(getText().length());
        }
    }
}

说一下注意的点:

1.不要实现三个参数的构造方法,否则无法获取焦点。

2.顺道解释一下圆角矩形为什么这么实现;从网上找的说法——先放大矩形:

新建位图图像

再放大左上角:

新建位图图像 (2)

如果我们设置strokekWidth为5的话,矩形的外圈坐标点是(-2.5,-2.5),内圈坐标点是(2.5,2.5),合起来横纵坐标都是5,但是canvas画矩形的时候是从(0,0)开始的,所以正常只会画一把只会画一半,这也是为什么我的divideLinePaint设置strokeWidth为1.5f的原因,所以实际矩形的边框为2.5;这时我们直接画圆角矩形:

canvas.drawRoundRect(storkRect, 20, 20, storkPaint);其中storkRect参数为(0,0,width,height),那么矩形就会是这样:

圆角矩形

矩形的四角很粗,因为矩形的边框是2.5,但是四个角的弧线确是实打实的5啊,所以我们设置storkRect的参数缩小2.5f,这样矩形的边框和四角弧线都是5了。

集合了一些简单自定义View的github地址:
https://github.com/longlong-2l/MySelfViewDemo
很简单,没有太多高深的用法,适合学习入门。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值