android EditText 限制输入条件的 4种方式

时间:2022-09-08 16:34:14
EditText 限制输入使用场景
         EditText 的用途十分广泛,android 中需要输入信息几乎都是通过它。 但某些时候我们必须要限制输入的内容。比如:只能输入数字?只能输入大写字符?只能输入自己定义的几个特殊字符?比如要限制输入的长度等等!

        这些都是对输入内容的限制,那么针对这些使用场景,我总结了以下四种有效、合理限制方式,希望能对你有所帮助!

        可以先下载Demo看下效果


**********************************************************************************************************************************************************************

使用XML实现的两种方式
(1)使用inputType
       如果你需要限制的条件是比较常见的,比如只能输入电话号码、只能输入邮件地址、域名地址、只能输入数字等,那么使用这种方式无疑是最简单、合适的。下面是一段只限数字的配置方式:
   <!--方法1 xml中配置inputType。-->
<EditText
android:id="@+id/et1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="只限数字(xml中 配置inputType)"
android:inputType="number" />


  inputType的更多选项可以参考http://blog.csdn.net/xqf222/article/details/9789143


(2)使用digits

        相对于inputType的方式,digits更加灵活。就是你可以自定义只限那些字符。如果你的限定范围不是太多的话,那么就可以直接自己写出限制的字符组,使用该属性。下面是一段只限给定的特殊字符、数字和英文大小写的配置方式:
   <!--方法2 xml中配置digits -->
<EditText
android:id="@+id/et2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:digits=" .@~-,:*?!#/\\=+?^;%$()[]{}|`<>&"'_0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLIMNOPQRSTUVWXYZ"
android:hint="只限自定义特殊字符(xml中 配置digits)"
/>


                                                                另:xml中部分特殊字符是不能直接写的,对应关系如下:
                                                                                              & --- & amp ;
                                                                                              < --- & lt ;
                                                                                              > --- & gt ;
                                                                                              ' --- & apos ;
                                                                                              " --- & quot ;


*************************************************************************************************************************************************************************


使用java实现的两种方式

       定义了三个字符串,分别用于下面三种方式

     

        private final static String ET3_DIGITS = "abcd";
private final static String ET4_DIGITS = "wxyz";
private final static String ET5_DIGITS = "jie";


(1) 使用setKeyListener,添加DigitsKeyListener
        这种方法其实就是xml中配置digits属性的具体实现。它的步奏也能简单,也是先给出字符串序列,然后使用该监听器,下面给出了一段只限“abcd”的具体实现。

         // 方式3:java中使用setKeyListener,添加DigitsKeyListener。
et3.setKeyListener(DigitsKeyListener.getInstance(ET3_DIGITS));


(2) 使用setFilters,添加InputFilter
         最后这种方法是最复杂的,但是也是扩展性最强大的。当你使用了该过滤器,你需要复写digits这个回调方法。它会传递给你即将输入的字符序列。你可以通过自己的一系列处理,然后将其返回。下面给出了一段只限“wxyz”的具体实现。
  
                // 方法4:java中使用setFilters,添加InputFilter。
et4.setFilters(new InputFilter[] { new InputFilter() {

@Override
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {

 StringBuffer sb = new StringBuffer();
for (int i = 0; i < source.length(); i++) {
if (ET4_DIGITS.indexOf(source.charAt(i)) >= 0) {
sb.append(source.charAt(i));
}
}
return sb;
}
} });


        所以四种方法中,这种方法也是最灵活的。你不仅可以限制只能输入哪些,而且还能限制不能输入哪些!你不仅可以限制字符串的长短,还能限制字符的大小 And so on!! 因为你拥有处理这些字符序列的所有权限。


*************************************************************************************************************************************************************************


为什么不推荐使用addTextChangedListener?

        很多人可能都会一下子想到使用这个监听器来进行字符输入限制!因为每当输入内容发生变化时都会回调这个监听器。

 

        但是使用它来限制字符输入是不太好的。是因为我们虽然在onTextChanged 或 afterTextChanged 回调方法中能得到的修改后的字符序列,但是并没有类似于上面InputFilter 接口中filter回调方法的返回值。也就是说 我们可以对修改后的字符串做处理,但是我们却不能将这个修改后的字符串设置回去。


        也许有人会想到使用setText方法。但是并不合适,因为如果你修改一次,然后去setText,它又会触发该监听。如果没有一个限制条件,那么就是一个死循环,最终导致栈溢出。并且即使你做了判定,也相当于修改一次,会触发两次监听也是不合理的。请参考如下代码:

      // 不推荐
// 方法5:java中使用addTextChangedListener,添加TextWatcher。
et5.addTextChangedListener(new TextWatcher() {

@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}

@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
StringBuffer sb = new StringBuffer();
for (int i = 0; i < s.length(); i++) {
if (ET5_DIGITS.indexOf(s.charAt(i)) >= 0) {
sb.append(s.charAt(i));
}
}
//如果没有改判定条件,每次直接调用,那么会报栈溢出异常,故易出错,不推荐(即使有了该判定条件,也相当于一次修改,会触发两次)
if (!sb.toString().equals(s.toString())) {
et5.setText(sb);
}
}
});


*************************************************************************************************************************************************************************


总结
  (1) 如果只是简单的常用限制条件,一定优先选择xml中配置inputType。
 (2) 如果限定特定字符,且字符数量不大的话,可以选择xml中配置digits(相对于java中使用setKeyListener,添加DigitsKeyListener。这种方式肯定更简单,明了)

 (3) 其他情况,如果限制条件相对复杂时,肯定是推荐使用这种最灵活的方式,也就是java中使用setFilters,添加InputFilter


*************************************************************************************************************************************************************************

Demo下载

    android EditText 限制输入的4种方法【修正版】