首先看看效果
如上图的密码输入框,没有密码时,有几个密码就有几条下划线,输入密码后显示的内容为“*”,并且底部就没有下划线了,同样有很多方式实现,这里就偷懒改改EditText来实现,所以需要做的就是画线、画“*”,代码很简单,偷懒也没有写attr,属性直接初始化写死了。这个思路同样适用于那些内容区域是方框的密码输入,就是画线和画矩形的区别。
public class PasswordUnderLineEditText extends EditText {
public interface TextIndexChangeListener {
void onTextIndexChange(CharSequence text, int index);
}
private TextIndexChangeListener mTextIndexChangeListener;
@ColorInt
private int lineColor;
private int lineCount;
private int lineMargin;
private int lineHeight;
private int linePaddingBottom;
private String changedText;
private int changedTextSize;
private int changedTextColor;
private int textLength;
private boolean isHideLineOnChanged;
private Paint mLinePaint;
private TextPaint mChangedTextPaint;
public PasswordUnderLineEditText(Context context) {
this(context, null);
}
public PasswordUnderLineEditText(Context context, AttributeSet attrs) {
super(context, attrs);
lineColor = getResources().getColor(R.color.gray);
changedTextColor = getResources().getColor(R.color.black);
lineCount = 6;
changedTextSize = DensityUtil.sp2px(context, 20);
lineMargin = DensityUtil.dp2px(context, 12);
linePaddingBottom = DensityUtil.dp2px(context, 10);
lineHeight = DensityUtil.dp2px(context, 1);
changedText = "*";
isHideLineOnChanged = true;
setGravity(Gravity.CENTER_VERTICAL);
setTextColor(getResources().getColor(android.R.color.transparent));
setBackgroundColor(Color.WHITE);
setCursorVisible(false);
setInputType(InputType.TYPE_CLASS_NUMBER);
setFilters(new InputFilter[]{new InputFilter.LengthFilter(lineCount)});
mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mLinePaint.setColor(lineColor);
mLinePaint.setStyle(Paint.Style.FILL);
mLinePaint.setStrokeWidth(lineHeight);
mChangedTextPaint = new TextPaint();
mChangedTextPaint.setColor(changedTextColor);
mChangedTextPaint.setTextSize(changedTextSize);
mChangedTextPaint.setStyle(Paint.Style.FILL);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int height = getHeight();
int width = getWidth();
canvas.save();
int singleLineWidth = width / lineCount;
int startX = 0;
int stopX = 0;
int startY = height - linePaddingBottom;
for (int i = 0; i < lineCount; i++) {
if (textLength == 0) {
startX = i * singleLineWidth + lineMargin;
stopX = (i + 1) * singleLineWidth - lineMargin;
canvas.drawLine(startX, startY, stopX, startY, mLinePaint);
} else if (textLength > 0) {
int changeIndex;
if (isHideLineOnChanged) {
changeIndex = textLength;
} else {
changeIndex = 0;
}
startX = (i + changeIndex) * singleLineWidth + lineMargin;
stopX = (i + changeIndex + 1) * singleLineWidth - lineMargin;
canvas.drawLine(startX, startY, stopX, startY, mLinePaint);
}
}
for (int i = 0; i < textLength; i++) {
startX = i * singleLineWidth + lineMargin;
stopX = (i + 1) * singleLineWidth - lineMargin;
canvas.drawText(changedText, (startX + stopX) / 2 - changedTextSize / 4, (height + changedTextSize) / 2, mChangedTextPaint);
}
canvas.restore();
}
@Override
protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
this.textLength = text.length();
invalidate();
if(mTextIndexChangeListener!=null){
mTextIndexChangeListener.onTextIndexChange(text,textLength);
}
}