android 支付密码输入框,Android-打造一个属于自己的支付密码输入框

首先上张效果图看看

91d8c9e59de3

device-2018-07-10-112505.gif

具体思路

1. 绘制外围Rect

2. 绘制分割线

3. 绘制圆点密码

大家看到边框、分割线、圆点密码的颜色、大小、都是通过自定义属性而获得。

91d8c9e59de3

ps.png

看这样一张图 我们首先需要绘制这样一个View

自定义属性

自定义密码输入框的View

public class PasswordEditText extends AppCompatEditText {

// 画笔-->绘制背景框

private Paint mRectPaint;

// 画笔--> 绘制密码

private Paint mPasswordPaint;

// 一个密码所占的宽度

private int mPasswordItemWidth;

// 密码的个数默认为6位数

private int mPasswordNumber = 6;

// 背景边框颜色

private int mBgColor = Color.parseColor("#d1d2d6");

// 背景边框大小

private int mBgSize = 1;

// 背景边框圆角大小

private int mBgCorner = 0;

// 分割线的颜色

private int mDivisionLineColor = mBgColor;

// 分割线的大小

private int mDivisionLineSize = 1;

// 密码圆点的颜色

private int mPasswordColor = Color.parseColor("#000000");

// 密码圆点的半径大小

private int mPasswordRadius = 4;

//密码输入完毕需要一个接口回调出去

private PasswordFullListener mPasswordFullListener;

public PasswordEditText(Context context) {

this(context, null);

}

public PasswordEditText(Context context, AttributeSet attrs) {

super(context, attrs);

initAttributeSet(context, attrs);

//不显示光标

setCursorVisible(false);

//不弹出系统软键盘

setInputType(InputType.TYPE_NULL);

setBackground(null);

initPaint();

}

/**

* 初始化属性

*/

private void initAttributeSet(Context context, AttributeSet attrs) {

TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.PasswordEditText);

// 获取大小

mDivisionLineSize = ( int ) array.getDimension(R.styleable.PasswordEditText_divisionLineSize, dip2px(mDivisionLineSize));

mPasswordRadius = ( int ) array.getDimension(R.styleable.PasswordEditText_passwordRadius, dip2px(mPasswordRadius));

mBgSize = ( int ) array.getDimension(R.styleable.PasswordEditText_bgSize, dip2px(mBgSize));

mBgCorner = ( int ) array.getDimension(R.styleable.PasswordEditText_bgCorner, 0);

// 获取颜色

mBgColor = array.getColor(R.styleable.PasswordEditText_bgColor, mBgColor);

mDivisionLineColor = array.getColor(R.styleable.PasswordEditText_divisionLineColor, mDivisionLineColor);

mPasswordColor = array.getColor(R.styleable.PasswordEditText_passwordColor, mPasswordColor);

array.recycle();

}

/**

* 初始化画笔

*/

private void initPaint() {

//初始化绘制边框的画笔

mRectPaint = new Paint();

mRectPaint.setAntiAlias(true);

mRectPaint.setDither(true);

mRectPaint.setColor(mBgColor);

//初始化密码远点的画笔

mPasswordPaint = new Paint();

mPasswordPaint.setAntiAlias(true);

mPasswordPaint.setDither(true);

mPasswordPaint.setColor(mPasswordColor);

}

@Override

protected void onDraw(Canvas canvas) {

//不需要调用super.onDraw(canvas); 为什么不需要呢?你去调用试试看,就明白为什么了

//super.onDraw(canvas);

//一个密码的宽度

mPasswordItemWidth = (getWidth() - mBgSize * 2 - (mPasswordNumber - 1) * mDivisionLineSize) / mPasswordNumber;

drawRect(canvas);

drawDivisionLine(canvas);

drawPassword(canvas);

if (mPasswordFullListener != null) {

//获取输入的密码

String password = getText().toString().trim();

if (password.length() == mPasswordNumber) {

mPasswordFullListener.passwordFull(password);

}

}

}

/**

* 绘制背景框

*

* @param canvas 画布

*/

private void drawRect(Canvas canvas) {

//矩形

RectF rect = new RectF(mBgSize, mBgSize, getWidth() - mBgSize, getHeight() - mBgSize);

mRectPaint.setStrokeWidth(mBgSize);

//画空心

mRectPaint.setStyle(Paint.Style.STROKE);

if (mBgCorner == 0) {

canvas.drawRect(rect, mRectPaint);

} else {

canvas.drawRoundRect(rect, mBgCorner, mBgCorner, mRectPaint);

}

}

/**

* 绘制分割线

*

* @param canvas 画布

*/

private void drawDivisionLine(Canvas canvas) {

mRectPaint.setStrokeWidth(mDivisionLineSize);

for (int i = 0; i < mPasswordNumber - 1; i++) {

int startX = mBgSize + (i + 1) * mPasswordItemWidth + i * mDivisionLineSize;

int startY = 0;

int endX = startX;

int endY = getHeight() - mBgSize;

canvas.drawLine(startX, startY, endX, endY, mRectPaint);

}

}

/**

* 绘制圆点密码

*

* @param canvas 画布

*/

private void drawPassword(Canvas canvas) {

//圆点密码是实行的

mPasswordPaint.setStyle(Paint.Style.FILL);

int length = getText().toString().length();

for (int i = 0; i < length; i++) {

int cx = mBgSize + i * mDivisionLineSize + i * mPasswordItemWidth + mPasswordItemWidth / 2;

int cy = getHeight() / 2;

canvas.drawCircle(cx, cy, mPasswordRadius, mPasswordPaint);

}

}

public void addPassword(String number) {

if (TextUtils.isEmpty(number)) {

return;

}

//把密码取取出来

String password = getText().toString().trim();

if (password.length() <= mPasswordNumber) {

//密码叠加

password += number;

setText(password);

}

}

/**

* 删除密码

*/

public void deletePassword() {

String password = getText().toString().trim();

if (TextUtils.isEmpty(password)) {

return;

}

password = password.substring(0, password.length() - 1);

setText(password);

}

private int dip2px(int dip) {

return ( int ) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,

dip, getResources().getDisplayMetrics());

}

/**

* 设置一个密码输入完毕的监听器

*

* @param passwordFullListener Listener

*/

public void setPasswordFullListener(PasswordFullListener passwordFullListener) {

this.mPasswordFullListener = passwordFullListener;

}

public interface PasswordFullListener {

void passwordFull(String password);

}

}

最主要的是去求出每个密码的宽度、分割线的坐标位置(float startX, float startY, float stopX, float stopY)和原点密码的(cx,cy);

91d8c9e59de3

key.png

在看这样一个数字键盘,是写一个这样的布局,很简单的。关键是怎么给每一个View设置一个点击事件。每一个View 我们都去绑定一个Id,然后设置onClick事件吗?这样做,那是不可能的。具体这样做,看代码

/**

* 给每一个自定义数字键盘上的View 设置点击事件

*

* @param view

*/

private void setItemClickListener(View view) {

if (view instanceof ViewGroup) {

ViewGroup viewGroup = ( ViewGroup ) view;

int childCount = viewGroup.getChildCount();

for (int i = 0; i < childCount; i++) {

//不断的给里面所有的View设置setOnClickListener

View childView = (( ViewGroup ) view).getChildAt(i);

setItemClickListener(childView);

}

} else {

view.setOnClickListener(this);

}

}

说下思路,键盘的整体布局是个LineaLayout,每一行布局是一个LineaLayout,然后每个LineaLayout会有三个子TextView。我们去递归下,这样每次循环都去拿View,不是ViewGroup,那就是View。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值