自定义键盘布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#EBEBEB"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="1dp"
android:layout_weight="1"
android:background="#FFFFFF"
android:gravity="center"
android:padding="20dp"
android:text="1" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="1dp"
android:layout_weight="1"
android:background="#FFFFFF"
android:gravity="center"
android:padding="20dp"
android:text="2" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#FFFFFF"
android:gravity="center"
android:padding="20dp"
android:text="3" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="1dp">
<TextView
android:id="@+id/textView3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="1dp"
android:layout_weight="1"
android:background="#FFFFFF"
android:gravity="center"
android:padding="20dp"
android:text="4" />
<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="1dp"
android:layout_weight="1"
android:background="#FFFFFF"
android:gravity="center"
android:padding="20dp"
android:text="5" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#FFFFFF"
android:gravity="center"
android:padding="20dp"
android:text="6" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="1dp">
<TextView
android:id="@+id/textView2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="1dp"
android:layout_weight="1"
android:background="#FFFFFF"
android:gravity="center"
android:padding="20dp"
android:text="7" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="1dp"
android:layout_weight="1"
android:background="#FFFFFF"
android:gravity="center"
android:padding="20dp"
android:text="8" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#FFFFFF"
android:gravity="center"
android:padding="20dp"
android:text="9" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="1dp"
android:orientation="horizontal">
<TextView
android:id="@+id/textView4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="1dp"
android:layout_weight="1"
android:gravity="center"
android:padding="20dp" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="1dp"
android:layout_weight="1"
android:background="#FFFFFF"
android:gravity="center"
android:padding="20dp"
android:text="0" />
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:padding="15dp"
android:layout_gravity="center_vertical"
android:src="@drawable/customer_password_keyboard_delete" />
</LinearLayout>
</LinearLayout>
自定义密码框
- 属性
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="PasswordEditText">
<!-- 密码的个数 -->
<attr name="passwordNumber" format="integer"/>
<!-- 密码圆点的半径 -->
<attr name="passwordRadius" format="dimension" />
<!-- 密码圆点的颜色 -->
<attr name="passwordColor" format="color" />
<!-- 分割线的颜色 -->
<attr name="divisionLineColor" format="color" />
<!-- 分割线的大小 -->
<attr name="divisionLineSize" format="dimension" />
<!-- 背景边框的颜色 -->
<attr name="bgColor" format="color" />
<!-- 背景边框的大小 -->
<attr name="bgSize" format="dimension" />
<!-- 背景边框的圆角大小 -->
<attr name="bgCorner" format="dimension"/>
</declare-styleable>
</resources>
自定义输入框
public class PasswordEditText extends EditText {
// 画笔
private Paint mPaint;
// 一个密码所占的宽度
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 = mDivisionLineColor;
// 密码圆点的半径大小
private int mPasswordRadius = 4;
public PasswordEditText(Context context) {
this(context, null);
}
public PasswordEditText(Context context, AttributeSet attrs) {
super(context, attrs);
initAttributeSet(context, attrs);
initPaint();
//设置默认只能设置数字和字母
setInputType(EditorInfo.TYPE_TEXT_VARIATION_PASSWORD);
}
/**
* 初始化画笔
*/
private void initPaint() {
mPaint = new Paint();
// 抗锯齿
mPaint.setAntiAlias(true);
// 防抖动
mPaint.setDither(true);
}
/**
* 初始化属性
*/
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, mDivisionLineColor);
array.recycle();
}
@Override
protected void onDraw(Canvas canvas) {
// 一个密码的宽度
mPasswordItemWidth = (getWidth() - 2 * mBgSize - (mPasswordNumber - 1) * mDivisionLineSize) / mPasswordNumber;
//画背景
drawBg(canvas);
// 画分割线
drawDivisionLine(canvas);
//画密码
drawPassWord(canvas);
}
/**
* 绘制密码
*/
private void drawPassWord(Canvas canvas) {
//设置为实心
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(mPasswordColor);
//获取输入框内容
String password = getText().toString().trim();
int length = password.length();
//for循环
for (int i = 0; i < length; i++) {
int cy=getHeight()/2;
int cx = mBgSize + i * mPasswordItemWidth + i * mDivisionLineSize + mPasswordItemWidth / 2;
canvas.drawCircle(cx,cy,mPasswordRadius,mPaint);
}
}
/**
* 画分割线
*/
private void drawDivisionLine(Canvas canvas) {
mPaint.setStrokeWidth(mDivisionLineSize);
mPaint.setColor(mDivisionLineColor);
for (int i = 0; i < mPasswordNumber-1; i++) {
float startX = (i+1)*mPasswordItemWidth+mBgSize+mDivisionLineSize;
float startY = mBgSize;
float endX = startX;
float endY = getHeight()-mBgSize;
canvas.drawLine(startX, startY, endX, endY, mPaint);
}
}
/**
* 绘制背景
*/
private void drawBg(Canvas canvas) {
//如果没有设置背景则 canvas.drawRect();
// RectF rect=new RectF(0,0,getWidth(),getHeight());
RectF rect = new RectF(mBgSize, mBgSize, getWidth() - mBgSize, getHeight() - mBgSize);
mPaint.setStrokeWidth(mBgSize);
//设置画笔为空心
mPaint.setStyle(Paint.Style.STROKE);
if (mBgCorner == 0) {
canvas.drawRect(rect, mPaint);
} else {
canvas.drawRoundRect(rect, mBgCorner, mBgCorner, mPaint);
}
}
/**
* px 转 dp
*/
private float dip2px(int dip) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dip, getResources().getDisplayMetrics());
}
/**
* 添加密码
*/
public void addPassWordNumber(String number) {
String passWord = getText().toString();
if(passWord.length()>=mPasswordNumber){//当前密码的长度大于当前密码数量return
return;
}
passWord+=number;
setText(passWord);
//判断是否添加密码是否添加完成
if(mListener!=null){
if(passWord.length()>=mPasswordNumber){
mListener.passwordFull(getText().toString().trim());
}
}
}
/**
* 删除密码
*/
public void deletePassWord() {
String passWord = getText().toString().trim();
if(passWord.length()<=0){
return;
}
passWord=passWord.substring(0,passWord.length()-1);
setText(passWord);
}
// 设置当前密码是否已满的接口回掉
private PasswordFullListener mListener;
public void setOnPasswordFullListener(PasswordFullListener listener){
this.mListener = listener;
}
/**
* 密码已经全部填满
*/
public interface PasswordFullListener {
public void passwordFull(String password);
}
}
CustomerKeyboard:自定义键盘
public class CustomerKeyboard extends LinearLayout implements View.OnClickListener {
public CustomerKeyboard(Context context) {
this(context, null);
}
public CustomerKeyboard(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomerKeyboard(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
LayoutInflater.from(context).inflate(R.layout.ui_customer_keyboard, this);
setItemClickListener(this);
}
/**
* 设置子view的点击事件
*/
public void setItemClickListener(View view) {
if (view instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) view;//LinearLayout
//继续遍历
int childCount = viewGroup.getChildCount();
for (int i = 0; i < childCount; i++) {
//不断遍历循环
View childView = viewGroup.getChildAt(i);
setItemClickListener(childView);
}
} else {
view.setOnClickListener(this);
}
}
@Override
public void onClick(View v) {
if (v instanceof TextView) {
String number = ((TextView) v).getText().toString().trim();
if(v.getId()==R.id.textView4){
Toast.makeText(getContext(),"改按钮不可点击",Toast.LENGTH_SHORT).show();
return;
}
if (mListener != null) {
mListener.click(number);
}
}
if(v instanceof ImageView){
if(mListener!=null){
mListener.delete();
}
}
}
// 设置点击回掉监听
private CustomerKeyboardClickListener mListener;
public void setOnCustomerKeyboardClickListener(CustomerKeyboardClickListener listener) {
this.mListener = listener;
}
/**
* 点击键盘的回调监听
*/
public interface CustomerKeyboardClickListener {
public void click(String number);
public void delete();
}
}
MainActivity中使用
mPasswordEditText = (PasswordEditText) findViewById(R.id.password_edit_text);
mCustomerKeyBoard = (CustomerKeyboard) findViewById(R.id.customer_key_board);
mPasswordEditText.setOnPasswordFullListener(this);
mCustomerKeyBoard.setOnCustomerKeyboardClickListener(new CustomerKeyboard.CustomerKeyboardClickListener() {
@Override
public void click(String number) {
//Toast.makeText(MainActivity.this,"点击了"+number,Toast.LENGTH_SHORT).show();
mPasswordEditText.addPassWordNumber(number);
}
@Override
public void delete() {
//Toast.makeText(MainActivity.this,"点击了删除",Toast.LENGTH_SHORT).show();
mPasswordEditText.deletePassWord();
}
});
@Override
public void passwordFull(String password) {
Toast.makeText(MainActivity.this,"你输入的密码是:"+password,Toast.LENGTH_SHORT).show();
}
最后:附上源码的位置:https://gitee.com/yijia_cn/Android_Advanced.git