//实现原理,监听EditText的输入,将输入或粘贴的值画到指定位置(设置字体间距也可以这样实现);监听系统复制粘贴应该也可以,大家可以试试
public class EditTextCodeView extends androidx.appcompat.widget.AppCompatEditText {
public Context context;
private float wX;
private float height;
private float mX;
private float rXY;
private Paint paint,paintText,paintCursor;
private float distance,distance2;
private String str="";
private boolean flag = true;
private RectF rectF1,rectF2,rectF3,rectF4,rectF5,rectF6;
private float clickBgWidth1,clickBgWidth2,clickBgWidth3,clickBgWidth4,clickBgWidth5,clickBgWidth6;
private boolean initFlag=true;
private Handler handler = new Handler(Looper.myLooper()){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
switch (msg.what){
case 0:
setInvalidate();
break;
}
}
};
public EditTextCodeView(Context context) {
super(context);
this.context=context;
}
public EditTextCodeView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
this.context=context;
}
public EditTextCodeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context=context;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (initFlag){
initFlag = false;
initData();
}
//这里是自定义每个数字的背景,(根据需求定义自己需要的,我这里是圆角边框)
rectF1 = new RectF(0,0,wX,height);
canvas.drawRoundRect(rectF1,rXY,rXY,paint);
rectF2 = new RectF(wX+mX,0,2*wX+mX,height);
canvas.drawRoundRect(rectF2,rXY,rXY,paint);
rectF3 = new RectF(2*wX+2*mX,0,3*wX+2*mX,height);
canvas.drawRoundRect(rectF3,rXY,rXY,paint);
rectF4 = new RectF(3*wX+3*mX,0,4*wX+3*mX,height);
canvas.drawRoundRect(rectF4,rXY,rXY,paint);
rectF5 = new RectF(4*wX+4*mX,0,5*wX+4*mX,height);
canvas.drawRoundRect(rectF5,rXY,rXY,paint);
rectF6 = new RectF(5*wX+5*mX,0,6*wX+5*mX,height);
canvas.drawRoundRect(rectF6,rXY,rXY,paint);
//光标初始化(也可以不初始化)
if (TextUtils.isEmpty(str)){
//文字的宽度
if (flag){
canvas.drawText("I", rectF1.centerX(),rectF1.centerY()+ distance2,paintCursor);
flag = false;
}else {
canvas.drawText("", rectF1.centerX(),rectF1.centerY()+ distance2,paintCursor);
flag = true;
}
}
//画出数字
for (int i=0;i<str.length();i++){
char charAt = str.charAt(i);
switch (i){
case 0:
float baseline1= rectF1.centerY()+ distance;
canvas.drawText(""+charAt, rectF1.centerX(),baseline1,paintText);
//判断是最后一个数字,显示光标
if (i==(str.length()-1)){
//文字的宽度
clickBgWidth1 = paintText.measureText(""+charAt);
if (flag){
canvas.drawText("I", rectF1.centerX()+clickBgWidth1/2+2,rectF1.centerY()+ distance2,paintCursor);
flag = false;
}else {
canvas.drawText("", rectF1.centerX()+clickBgWidth1/2+2,rectF1.centerY()+ distance2,paintCursor);
flag = true;
}
}
break;
case 1:
float baseline2= rectF2.centerY()+ distance;
canvas.drawText(""+charAt, rectF2.centerX(),baseline2,paintText);
//判断是最后一个数字,显示光标
if (i==(str.length()-1)){
//文字的宽度
clickBgWidth2 = paintText.measureText(""+charAt);
if (flag){
canvas.drawText("I", rectF2.centerX()+clickBgWidth2/2+2,rectF2.centerY()+ distance2,paintCursor);
flag = false;
}else {
canvas.drawText("", rectF2.centerX()+clickBgWidth2/2+2,rectF2.centerY()+ distance2,paintCursor);
flag = true;
}
}
break;
case 2:
float baseline3= rectF3.centerY()+ distance;
canvas.drawText(""+charAt, rectF3.centerX(),baseline3,paintText);
//判断是最后一个数字,显示光标
if (i==(str.length()-1)){
//文字的宽度
clickBgWidth3 = paintText.measureText(""+charAt);
if (flag){
canvas.drawText("I", rectF3.centerX()+clickBgWidth3/2+2,rectF3.centerY()+ distance2,paintCursor);
flag = false;
}else {
canvas.drawText("", rectF3.centerX()+clickBgWidth3/2+2,rectF3.centerY()+ distance2,paintCursor);
flag = true;
}
}
break;
case 3:
float baseline4= rectF4.centerY()+ distance;
canvas.drawText(""+charAt, rectF4.centerX(),baseline4,paintText);
//判断是最后一个数字,显示光标
if (i==(str.length()-1)){
//文字的宽度
clickBgWidth4 = paintText.measureText(""+charAt);
if (flag){
canvas.drawText("I", rectF4.centerX()+clickBgWidth4/2+2,rectF4.centerY()+ distance2,paintCursor);
flag = false;
}else {
canvas.drawText("", rectF4.centerX()+clickBgWidth4/2+2,rectF4.centerY()+ distance2,paintCursor);
flag = true;
}
}
break;
case 4:
float baseline5= rectF5.centerY()+ distance;
canvas.drawText(""+charAt, rectF5.centerX(),baseline5,paintText);
//判断是最后一个数字,显示光标
if (i==(str.length()-1)){
//文字的宽度
clickBgWidth5 = paintText.measureText(""+charAt);
if (flag){
canvas.drawText("I", rectF5.centerX()+clickBgWidth5/2+2,rectF5.centerY()+ distance2,paintCursor);
flag = false;
}else {
canvas.drawText("", rectF5.centerX()+clickBgWidth5/2+2,rectF5.centerY()+ distance2,paintCursor);
flag = true;
}
}
break;
case 5:
float baseline6= rectF6.centerY()+ distance;
canvas.drawText(""+charAt, rectF6.centerX(),baseline6,paintText);
//判断是最后一个数字,显示光标
if (i==(str.length()-1)){
//文字的宽度
clickBgWidth6 = paintText.measureText(""+charAt);
if (flag){
canvas.drawText("I", rectF6.centerX()+clickBgWidth6/2+2,rectF6.centerY()+ distance2,paintCursor);
flag = false;
}else {
canvas.drawText("", rectF6.centerX()+clickBgWidth6/2+2,rectF6.centerY()+ distance2,paintCursor);
flag = true;
}
}
break;
}
}
handler.removeMessages(0);
handler.sendEmptyMessageDelayed(0,500);
}
private void initData() {
paint = new Paint();
paint.setColor(getResources().getColor(R.color.color_all));
wX = (getWidth() - (Util.dip2px(context, 14) * 5)) / 6;//子view宽度
mX = Util.dip2px(context, 14);//边距
rXY = Util.dip2px(context, 4);//圆角
height = Util.dip2px(context, 60);//高度
paintText = new Paint();
/*画上数字*/
paintText.setColor(Color.BLACK);
paintText.setTextSize(60);
paintText.setStyle(Paint.Style.FILL);
paintText.setTextAlign(Paint.Align.CENTER);
//计算baseline
Paint.FontMetrics fontMetrics=paintText.getFontMetrics();
distance = (fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom;
paintCursor = new Paint();
paintCursor.setColor(Color.BLACK);
paintCursor.setTextSize(80);
paintCursor.setStyle(Paint.Style.FILL);
paintCursor.setTextAlign(Paint.Align.CENTER);
//计算baseline
Paint.FontMetrics fontMetrics2=paintCursor.getFontMetrics();
distance2 = (fontMetrics2.bottom - fontMetrics2.top)/2 - fontMetrics2.bottom;
}
public void setOnPaintText(String str){
this.str = str;
}
public void setInvalidate(){
//更新绘制
invalidate();
}
/**
* @description 销毁
* @param
*/
public void setDestroy(){
if (handler!=null){
handler.removeCallbacksAndMessages(null);
handler=null;
}
}
}
<!--布局,字体颜色和背景色一个颜色-->
<com......EditTextCodeView
android:id="@+id/et_code_view"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_60"
android:layout_marginTop="@dimen/dp_30"
android:cursorVisible="false"
android:maxLength="6"
android:inputType="number"
android:digits="0123456789"
android:textColor="@color/white"
android:background="@null"/>
//当前类调用控件和EditText的输入监听
EditTextCodeView et_code_view = view.findViewById(R.id.et_code_view);
et_code_view.setSelection(et_code_view.length());//将光标移至文字末尾
et_code_view.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
et_code_view.setOnPaintText(editable.toString());
//et_code_view.setInvalidate();//刷新
}
});
//直接粘贴就可以使用
自定义验证码输入框
最新推荐文章于 2022-03-25 16:52:01 发布