一个带有正则匹配的EditText

作者: 卡咔喀 | 来源:发表于2017-08-31 14:23 被阅读328次

先上效果:

说明:

图中的EditText能够在失去焦点后验证输入框中的文本是否与正则表达式匹配,这里我设置的是5位整数(\d{5}),当输入110时,不匹配,边框变红并抖动,文本清除(gif中白色文本是因为录制的问题,实际文本已清除);输入12306,匹配,边框变绿。

实现方式

继承EditText,实现构造方法

注意构造方法中要传入官方的属性值,否则很多EditText属性不能在XML里面定义,并且EditText获取焦点后不会弹出软键盘

  public WarnningEditText(Context context) {
      this(context, null);
  }

  public WarnningEditText(Context context, AttributeSet attrs) {
      //这里构造方法也很重要,不加这个很多属性不能在XML里面定义
      this(context, attrs, android.R.attr.editTextStyle);
  }

  public WarnningEditText(Context context, AttributeSet attrs, int defStyle) {
      super(context, attrs, defStyle);
      //获取属性值
      TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.WarnningEditText);
      borderColor = ta.getColor(R.styleable.WarnningEditText_borderColor, Color.GRAY);
      correctBorderColor = ta.getColor(R.styleable.WarnningEditText_correctBorderColor, Color.GREEN);
      warinningBorderColor = ta.getColor(R.styleable.WarnningEditText_warinningBorderColor, Color.RED);
      borderWidth = ta.getDimensionPixelSize(R.styleable.WarnningEditText_borderWidth, 2);
      angleRadius = ta.getDimensionPixelSize(R.styleable.WarnningEditText_angleRadius, 5);
      ta.recycle();
      init();
  }

重写onDraw,绘制边框

注意边框的颜色不要设置常量

@Override
 protected void onDraw(Canvas canvas) {
     super.onDraw(canvas);
     //确定View宽高
     width = getWidth();
     height = getHeight();
     //边框的坐标范围
     r = new RectF(dp2px(borderWidth), dp2px(borderWidth), width - dp2px(borderWidth), height - dp2px(borderWidth));
     //设置画布绘图无锯齿
     canvas.setDrawFilter(mPaintFlagsDrawFilter);
     drawBorder(canvas);
 }

 /**
  * 绘制边框
  */
 private void drawBorder(Canvas canvas) {
     canvas.save();
     canvas.drawRoundRect(r, dp2px(angleRadius), dp2px(angleRadius), borderPaint);//绘制圆角矩形
     canvas.restore();
 }

重写onFocusChanged,监听焦点变化

获取焦点后,边框就设置为默认的颜色(灰色),失去焦点后,会判断是否匹配正则表达式。

 /**
  * 焦点变化
  */
 @Override
 protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
     super.onFocusChanged(focused, direction, previouslyFocusedRect);
     if (focused) {
         borderPaint.setColor(borderColor);
         postInvalidate();
     } else {
         if (!this.getText().toString().equals("")) {
             if (regex != null) {
                 if (!this.getText().toString().matches(regex)) {
                     inputError();
                     onInputMatchListener.onInputWrong();
                     Log.v(TAG, "wrong input");
                 } else {
                     borderPaint.setColor(correctBorderColor);
                     postInvalidate();
                     onInputMatchListener.onInputCorrect();
                     Log.v(TAG, "good input");
                 }
             } else {
                 Log.e(TAG, "no regex");
             }
         } else {
             Log.e(TAG, "no input");
         }
     }
 }

创建接口

创建一个OnInputMatchListener的接口,内含onInputWrong和onInputCorrect两个抽象方法,分别在判断文本不匹配正则表达式和匹配表达式时回调,回调地址在上面的代码中。

 public interface OnInputMatchListener {
     void onInputWrong();

     void onInputCorrect();
 }

使用

在布局文件中使用:

<com.example.ast.dashboard.WarnningEditText
     android:id="@+id/warnning_et2"
     android:layout_width="200dp"
     android:layout_height="40dp"
     android:background="@null"
     android:layout_centerHorizontal="true"
     android:paddingLeft="10dp"   
     android:textCursorDrawable="@drawable/color_cursor" />

设置接口:

     WarnningEditText warnningEditText = (WarnningEditText) findViewById(R.id.warnning_et);
     warnningEditText.setRegex("^\\d{5}$");
     warnningEditText.setOnInputMatchListener(new WarnningEditText.OnInputMatchListener() {
         @Override
         public void onInputWrong() {
             Toast.makeText(MainActivity.this, "输入错误", Toast.LENGTH_SHORT).show();
         }

         @Override
         public void onInputCorrect() {
             Toast.makeText(MainActivity.this, "输入正确", Toast.LENGTH_SHORT).show();
         }
     });

要注意的是:

  1. android:paddingLeft="10dp"让文本不是从左边框开始,而是左边框靠左一点。
  1. 组件的父布局可以加上
    android:focusable="true"
    android:focusableInTouchMode="true"

这样可以避免EditText默认获取焦点
3.重中之重:要加上android:background="@null"
我们知道android:background="@null"可以去掉EditText默认样式的下划线:


但在我自定义EditText的时候,我的边框是根据组件的宽高贴着边缘画的,当组件高度大于42dp时,一切正常:


当高度小于42时,比如30dp,边框上部就会缺失,或者说边框绘制
就会从组件外部开始:

想要解决问题就是要在布局文件加入:

android:background="@null

至于为什么这样我也不知道,还请大神指点一番。

这个组件的不太好用,不过还是贴一下源码:

https://github.com/xiaoniu/WarnningEditText

相关文章

  • 一个带有正则匹配的EditText

    先上效果: 说明: 图中的EditText能够在失去焦点后验证输入框中的文本是否与正则表达式匹配,这里我设置的是5...

  • NSRegularExpression 正则匹配带有表情emoj

    当用NSRegularExpression去正则匹配带有表情emoji的字符串的时候,会出现匹配不全的情况 例: ...

  • bootstrap集锦

    第一发:自己写的bootstrap提交用户信息的表单,带有用户的正则和电话号码的正则匹配

  • vscode 设置文件显示和搜索正则过滤

    使用 ⇧⌘F 搜索文件。并且可以使用正则匹配搜索,比如: 如果输入 example,会匹配工作区内所有命名带有 e...

  • 正则匹配库

    正则匹配用户名: 正则匹配用户名: 正则匹配手机号或者固定电话: 匹配中文: 正则匹配用户密码: 正则匹配电子邮箱...

  • RegExp类型

    每个正则表达式都可带有一个或多个标志,用以标明正则表达式的行为。正则表达式的匹配模式支持下列3个标志: g:表示全...

  • Nginx location的正则匹配

    Nginx location的正则匹配 Nginx正则匹配的匹配规则

  • nginx的location匹配

    location匹配命令~ #波浪线表示执行一个正则匹配,区分大小写~* #表示执行一个正则匹配,...

  • 正则表达式介绍

    正则表达式是匹配模式,匹配字符或者匹配位置。 一、字符匹配 1.两种模糊匹配 1.1 横向模糊匹配 一个正则可匹配...

  • Java中正则表达式匹配单行注释和多行注释

    匹配一个/** ... */注释块儿的正则表达式 \/\*(\s|.)*?\*\/ 匹配一个//注释块儿的正则表达...

网友评论

    本文标题:一个带有正则匹配的EditText

    本文链接:https://www.haomeiwen.com/subject/pkfqjxtx.html