学习地址
![](https://img.haomeiwen.com/i1945114/d8a7a2062ee18ebf.gif)
![](https://img.haomeiwen.com/i1945114/bb0ddfd95f395473.gif)
它可以干什么?
1、输入到了最大的个数后,会回调返回输入的值
2、可以自定义边框的颜色,边框弧度
3、可以自定义圆圈的颜色,半径
4、可以自定义个数
5、可以通过在XML里面定义 isPassword,true表示开启秘密模式,false关闭秘密模式,当为false的时候,我们可以拿去当验证码的输入,可以通过iTextSise控制文字大小
遇到的难点
1、如果我输入123,然后分别拆分到3个正方形的框框里
我们需要将123,进行分别拆分,拆分为1 2 3 这样的,在for循环里面通过canvas.drawText,绘画出每一个拆分的
代码展示
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".MainActivity">
<com.example.myapplication.InputEditViewLayout
android:id="@+id/inputEditView"
android:layout_width="match_parent"
android:layout_height="60dp"
app:passwordNumber="4"
app:isPassword="false"//关闭密码模式
app:iTextSise = "30"//设置文字大小,仅仅在isPassword=false有效
app:passwordColor="@color/colorAccent"
app:bgColor="@color/colorPrimary" />
</LinearLayout>
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final InputEditViewLayout inputEditViewLayout = this.findViewById(R.id.inputEditView);
inputEditViewLayout.setOnInputPassworEditListener(new InputEditViewLayout.OnInputPassworEditListener() {
@Override
public void onFinishInput() {
Toast.makeText(MainActivity.this,"密码是:"+ inputEditViewLayout.getText().toString(),Toast.LENGTH_LONG).show();
}
});
}
}
/**
* @date :2019/8/29 0029
* @author : gaoxiaoxiong
* @description: 密码框的输入
**/
public class InputEditViewLayout extends androidx.appcompat.widget.AppCompatEditText implements View.OnKeyListener {
private String TAG = InputEditViewLayout.class.getSimpleName();
private Paint mPaint;
// 一个密码所占的宽度
private int mPasswordItemWidth;
// 密码的个数默认为6位数
private int mPasswordNumber = 6;
// 背景边框颜色
private int mBgColor = Color.parseColor("#999999");
// 背景边框大小
private int mBgSize = 1;
// 背景边框圆角大小
private int mBgCorner = 0;
// 密码圆点的颜色
private int mPasswordColor = mBgColor;
// 密码圆点的半径大小
private int mPasswordRadius = 4;
private int itemDisTance = 0;//Item之间的间隔
private int paddingTop = dip2px(10);
private boolean isPassWord = true;//是否为密码模式,如果不是密码模式,就明文展示
private int iTextSise = 14;
private boolean isHaveNotice = false;//判断是否已经回调给前面了
public InputEditViewLayout(Context context) {
this(context, null);
}
public InputEditViewLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
private OnInputPassworEditListener onInputPassworEditListener;
@Override
public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
if(keyCode == KeyEvent.KEYCODE_DEL) {
isHaveNotice = false;
}
return false;
}
public interface OnInputPassworEditListener {
void onFinishInput();
}
public void setOnInputPassworEditListener(OnInputPassworEditListener onInputPassworEditListener) {
this.onInputPassworEditListener = onInputPassworEditListener;
}
public InputEditViewLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//初始化一些布局必须参数
initAttributeSet(context, attrs);
//初始化画笔 + 个数计算
init();
// 设置输入模式是密码
if (isPassWord){
setInputType(EditorInfo.TYPE_TEXT_VARIATION_PASSWORD);
}else {
setInputType(EditorInfo.TYPE_CLASS_NUMBER);
}
// 不显示光标
setCursorVisible(false);
//获取焦点
this.setFocusable(true);
this.setFocusableInTouchMode(true);
this.requestFocus();
setOnKeyListener(this);
}
private void initAttributeSet(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.InputEditViewLayout);
mBgSize = typedArray.getInteger(R.styleable.InputEditViewLayout_bgSize, 1);
mPasswordNumber = typedArray.getInteger(R.styleable.InputEditViewLayout_passwordNumber, 6);
mBgCorner = typedArray.getInteger(R.styleable.InputEditViewLayout_bgCorner, 5);
mPasswordRadius = typedArray.getInteger(R.styleable.InputEditViewLayout_passwordRadius, 4);
mPasswordColor = typedArray.getColor(R.styleable.InputEditViewLayout_passwordColor, mBgColor);
mBgColor = typedArray.getColor(R.styleable.InputEditViewLayout_bgColor, mBgColor);
isPassWord = typedArray.getBoolean(R.styleable.InputEditViewLayout_isPassword, true);
iTextSise = typedArray.getInteger(R.styleable.InputEditViewLayout_iTextSise,16);
typedArray.recycle();
mBgSize = dip2px(mBgSize);
mBgCorner = dip2px(mBgCorner);
mPasswordRadius = dip2px(mPasswordRadius);
iTextSise = sp2px(context,iTextSise);
this.setFilters(new InputFilter[]{new InputFilter.LengthFilter(mPasswordNumber)});
}
private void init() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(mBgColor);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mPasswordItemWidth = getMeasuredHeight() - paddingTop;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
itemDisTance = (getWidth() - (mPasswordNumber * mPasswordItemWidth)) / (mPasswordNumber + 1);//平均下来的距离
}
@Override
protected void onDraw(Canvas canvas) {
//绘制背景
drawBg(itemDisTance, canvas);
drawHidePassword(canvas);
}
/**
* @date :2019/8/29 0029
* @author : gaoxiaoxiong
* @description:绘制背景
**/
private void drawBg(int startX, Canvas canvas) {
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(mBgColor);
mPaint.setStrokeWidth(mBgSize);
for (int i = 0; i < mPasswordNumber; i++) {
RectF rectF = new RectF(startX, paddingTop / 2, startX + mPasswordItemWidth, mPasswordItemWidth + paddingTop / 2);
canvas.drawRoundRect(rectF, mBgCorner, mBgCorner, mPaint);
startX = startX + mPasswordItemWidth + itemDisTance;
}
}
/**
* @date :2019/8/29 0029
* @author : gaoxiaoxiong
* @description:绘制密码
**/
private void drawHidePassword(Canvas canvas) {
int passwordLength = getText().toString().trim().length();
mPaint.setColor(mPasswordColor);
mPaint.setStyle(Paint.Style.FILL);
if (!isPassWord) {//不是密码模式
mPaint.setTextSize(iTextSise);
String text = getText().toString();//1 2 3
for (int i = 0; i < passwordLength; i++) {
int cx = itemDisTance + i * mPasswordItemWidth + mPasswordItemWidth / 2 + i * itemDisTance;
String aaa = text.substring(i, i + 1);
//文字处理
TextPaint paint = this.getPaint();
//计算baseLine
int center = getMeasuredHeight() / 2 + paddingTop / 2;
int baseLine = (int) (center + (paint.getFontMetrics().bottom - paint.getFontMetrics().top) / 2 - paint.getFontMetrics().bottom);
int fontWidth = (int) mPaint.measureText(aaa);
canvas.drawText(aaa, cx - fontWidth / 2, baseLine, mPaint);
}
} else {
//密码处理
for (int i = 0; i < passwordLength; i++) {
int cx = itemDisTance + i * mPasswordItemWidth + mPasswordItemWidth / 2 + i * itemDisTance;
canvas.drawCircle(cx, getHeight() / 2, mPasswordRadius, mPaint);
}
}
if (passwordLength == mPasswordNumber && !isHaveNotice) {
if (onInputPassworEditListener != null) {
onInputPassworEditListener.onFinishInput();
isHaveNotice = true;
}
}
}
/**
* @date :2019/9/24 0024
* @author : gaoxiaoxiong
* @description:清除数据
**/
public void cleanData(){
this.setText("");
isHaveNotice = false;
}
/**
* dip 转 px
*/
private int dip2px(int dip) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dip, getResources().getDisplayMetrics());
}
/**
* 将px值转换为sp值,保证文字大小不变
*
* @param pxValue
* @return
*/
public int px2sp(Context context, float pxValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (pxValue / fontScale + 0.5f);
}
/**
* 将sp值转换为px值,保证文字大小不变
*
* @param spValue
* @return
*/
public int sp2px(Context context, float spValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}
}
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="InputEditViewLayout">
<!-- 密码的个数 -->
<attr name="passwordNumber" format="integer"/>
<!-- 密码圆点的半径 -->
<attr name="passwordRadius" format="integer" />
<!-- 密码圆点的颜色 -->
<attr name="passwordColor" format="color" />
<!-- 分割线的颜色 -->
<attr name="divisionLineColor" format="color" />
<!-- 分割线的大小 -->
<attr name="divisionLineSize" format="color" />
<!-- 背景边框的颜色 -->
<attr name="bgColor" format="color" />
<!-- 背景边框的大小 -->
<attr name="bgSize" format="integer" />
<!-- 背景边框的圆角大小 -->
<attr name="bgCorner" format="integer"/>
<!--是否为密码模式-->
<attr name="isPassword" format="boolean"/>
<!--文字大小,仅仅对,明文模式有效-->
<attr name="iTextSise" format="integer"/>
</declare-styleable>
</resources>
网友评论