android_基础_editText字符过滤

转载自:https://www.jianshu.com/p/2bb465ce7880?from=timeline@

EditText字符过滤

我们使用EditText控件的时候,可能会遇到这样一种情况,在输入的时候,要求禁止输入某些字符。如输入$,#等特殊字符的时候,使其输入无效。这就是字符的过滤。要实现该效果,可以有多种方法,下面将一一介绍:

1.android:inputType

这是最常见的一种字符过滤的方法了,通过设置inputType标签属性,可以控制输入内容的类型,如android:inputType=“password”,这表示输入的内容应该为密码;而android:inputType="text"时,则表示输入的内容是文本。

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="text" />

在java中,则可使用setInputType来设置:

    etText.setInputType(InputType.TYPE_CLASS_TEXT)
    

2.android:digits

如果需要更详细的对输入内容进行控制,可使用android:digits属性。只要在该属性设置允许输入的所有字符,就可以达到字符过滤的效果。比如,要让EditText只能输入数字,可以这样写

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:digits="1234567890" />

只能输入数字和英语,则如下

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:digits="1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" />

这样,在点击键盘上的其他字符时(@,#,!等),都不会输入到输入框中。

3.InputFilter

如果仅仅是限制几个字符的输入,那么使用android:digits属性就不好进行处理了,因为设置一大堆字符。在这样的情况下,我们可以使用InputFilter来进行字符过滤。在实现InputFilter的时候,需要覆盖InputFilter的filter方法:

    InputFilter filter = new InputFilter() {
    
    
      @Override
      public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    
    
        return null;
      }
    }

其中的source变量即为输入的字符内容,可以对其进行判断并做处理。如控制不允许输入空格,可以这样写:

    InputFilter filter1 = new InputFilter() {
    
    
      @Override
      public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    
    
        // 判断是否输入空格
        if (" ".equals(source)) {
    
    
          return "";
        }
        return null;
      }
    }

禁止输入多种特殊字符,如下:

    InputFilter filter2 = new InputFilter() {
    
    
      @Override
      public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    
    
        String spec = "!@#$%^&*()<>{}[]";
        // Reg表达式
        Pattern pattern = Pattern.compile(spec);
        Matcher matcher = pattern.matcher(source.toString());
        // 否有匹配结果
        if (matcher.find()) {
    
    
          return "";
        }
        return null;
      }
    }

创建了InputFilter以后,通过EditText的setFilters(InputFilter filters[])方法,注册InputFilter,EditText即可通过InputFilter的规则进行字符控制。setFilters方法传入的是一个InputFilter数组,这意味着你可以创建多个InputFilter,并注册在同一个EditText上。

扫描二维码关注公众号,回复: 14272656 查看本文章
    // 注册InputFilter
    etText.setFilters({
    
    filter1, filter2});

4.keyListener

InputFilter提供了字符过滤,那么keyListener则提供了对键盘按键的监听。常用的keyListener有两种,一个是NumberKeyListener,用于字符监听;另外一个是DigitsKeyListener用于数字监听。DigitsKeyListener继承NumberKeyListener,而NumberKeyListener实现了InputFilter:

    // 仅接受整数输入
    KeyListener l = new DigitsKeyListener(false, false);
    // 接受有符号的整数输入
    KeyListener l = new DigitsKeyListener(true, false);
    // 接受整数、小数输入
    KeyListener l = new DigitsKeyListener(false, true);
    // 接受有符号的整数、小数输入
    KeyListener l = new DigitsKeyListener(true, true);
    et.setKeyListener(l);
    
    //字符输入过滤
    et.setKeyListener(new NumberKeyListener() {
    
    
      @NonNull
      @Override
      protected char[] getAcceptedChars() {
    
    
        // 返回可输入字符,相当于android:digits
        return "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();;
      }
    
      @Override
      public int getInputType() {
    
    
        // 返回输入类型,相当于android:inputType
        return InputType.TYPE_CLASS_TEXT;
      }
    });

可以看出,NumberKeyListener的用法和android:digits属性的使用方法相近。

5.TextWatcher

TextWatcher的作用是用于监听输入变化。当EditText设置了TextWatcher监听时,往输入框输入内容时,都会调用TextWatcher的函数。当使用键盘输入时,每输入一个字,就会调用一次TextWatcher的函数;当使用复制粘贴时,每粘贴一次内容,就会调用一次TextWatcher的函数:

    TextWatcher textWatcher = new TextWatcher() {
    
    
      @Override
      public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    
    
                    
      }
    
      @Override
      public void onTextChanged(CharSequence s, int start, int before, int count) {
    
    
    
       }
    
      @Override
      public void afterTextChanged(Editable s) {
    
    
    
      }
    };
    et.addTextChangedListener(textWatcher);

TextWathcer有三个函数,这里我们一一进行分析:

1.beforeTextChanged(CharSequence s, int start, int count, int after)

该函数在输入内容改变之前调用,表示原有文本s,在从start开始count的长度,会被一个长度为after的文本代替。

2.onTextChanged(CharSequence s, int start, int before, int count)

该函数在内容改变的过程中调用,表示文本s从start开始到count长度的文本,替换了之前长度为before的文本。该函数调用的时候,文本内容已经被替换。

3.afterTextChanged(Editable s)

该函数在内容改变之后调用,其中s表示改变后的内容,可以使用Editable s的方法对文本进行处理。
对字符过滤,主要在onTextChanged(CharSequence s, int start, int before, int count) 方法中处理,对已经替换的文本内容进行过滤:

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
    
    
      String reg = "@#$%^&*()?";
      Pattern pattern = Pattern.compile(reg);
      Matcher match = Pattern.matcher(s.toString());
      // 替换所有特殊字符
      String str = match.replaceAll("").trim();
      et.setText(str); 
    }

5.EditText的InputConnection属性
此方法参考自博主brycegao321,原理是继承EditText,然后使用inputConnection属性限制字符输入

    public class LimitEditText extends EditText {
    
    
        public LimitEditText(Context context) {
    
    
            super(context);
        }
    
        public LimitEditText(Context context, AttributeSet attrs) {
    
    
            super(context, attrs);
        }
    
        public LimitEditText(Context context, AttributeSet attrs, int defStyleAttr) {
    
    
            super(context, attrs, defStyleAttr);
        }
    
        /**
         * 输入法
         * @param outAttrs
         * @return
         */
        @Override
        public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
    
    
            return new InnerInputConnecttion(super.onCreateInputConnection(outAttrs),
                    false);
        }
    
        class InnerInputConnecttion extends InputConnectionWrapper implements InputConnection {
    
    
    
            public mInputConnecttion(InputConnection target, boolean mutable) {
    
    
                super(target, mutable);
            }
    
            /**
             * 对输入的内容进行拦截
             *
             * @param text
             * @param newCursorPosition
             * @return
             */
            @Override
            public boolean commitText(CharSequence text, int newCursorPosition) {
    
    
                // 只能输入字母或者数字
                if (!Character.isLetterOrDigit(charSequence.charAt(i)) || isChinese)  {
    
    
                    return false;
                }
                return super.commitText(text, newCursorPosition);
            }
    
            @Override
            public boolean sendKeyEvent(KeyEvent event) {
    
    
                return super.sendKeyEvent(event);
            }
    
            @Override
            public boolean setSelection(int start, int end) {
    
    
                return super.setSelection(start, end);
            }
        }
    }

最后,列出大神写的博客:
Android EditText实现字符过滤
Android EditText限制输入字符的5种实现方式
onTextChanged使用详解

6. setFilters使用解析

android输入框有时候需要添加各种各样的限制条件,仅仅限制长度的属性(maxLength)或方法(length())是不能满足我们的需求的,如你需要这个输入框要求只能输入数字或字母又或者是大小写字母之类的,这时候可以用setFilters

使用步骤

1)首先需要先获取你的输入框的控件:EditText et_psw = (EditText) findViewById(R.id.et_login_psw);

2)获得的控件调用setFilters()方法 里边是一个new InputFilter的类型,例如 密码输入框的长度不能超过12,直相关代码 et_psw.setFilters(new InputFilter[]{new InputFilter.LengthFilter(12)});

但是此时你不仅需要密码的长度有限制还需要密码的格式例如 禁止特殊字符的输入:

InputFilter codeInputFilter = new codeInputFilter();
	et_psw.setFilters(new InputFilter[]{
    
    codeInputFilter  , new InputFilter.LengthFilter(16)});
//这个方法,返回空字符串,就代表匹配不成功,返回null代表匹配成功
private class codeInputFilter implements InputFilter{
    
    
	@Override
	public CharSequence filter(CharSequence source, int start, int end,Spanned dest, int dstart, int dend) {
    
    
   	//在这里边写限制代码
	//source    新输入的字符串    
	//start    新输入的字符串起始下标,一般为0    
	//end    新输入的字符串终点下标,一般为source长度-1    
	//dest    输入之前文本框内容    
	//dstart    原内容起始坐标,一般为0    
	//dend    原内容终点坐标,一般为dest长度-1
	String tem = "";
	String digits = "/\\:*?<>|\"\n\t";
	for(int i=0 ;i<source.length();i++){
    
    
		if (digits.indexOf(source.charAt(i)) < 0) {
    
    
	  	//不含特殊字符 匹配成功
	  	return null;
	  	}
	}
	//匹配不成功!
	return tem ;
	}
}

猜你喜欢

转载自blog.csdn.net/qq_42420293/article/details/122573743