今天我们要实现的效果如下,支付宝的支付密码输入框
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>
网友评论