自定义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.顺道解释一下圆角矩形为什么这么实现;从网上找的说法——先放大矩形:
再放大左上角:
如果我们设置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
很简单,没有太多高深的用法,适合学习入门。