在android中使用输入过滤器作为edittext

时间:2014-09-28 04:03:23

标签: java android

我正在为edittext使用输入过滤器,我有以下要求:

1)第一个字符不应该是数字 2)从第二个字符开始,允许使用字母,数字,下划线和点

我从帖子中获得了以下代码:

filter_username = new InputFilter() { 
         public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
                boolean keepOriginal = true;
                 sb = new StringBuilder(end - start);
                for (int i = start; i < end; i++) {

                    char c = source.charAt(i);
//                  testString.append(c);
                    if (isCharAllowed2(c)) // put your condition here
                        sb.append(c);
                    else
                        keepOriginal = false;
                }
                if (keepOriginal)
                    return null;
                else {
                    if (source instanceof Spanned) {
                        SpannableString sp = new SpannableString(sb);
                        TextUtils.copySpansFrom((Spanned) source, start, sb.length(), null, sp, 0);
                        return sp;
                    } else {
                        return sb;
                    }           
                }
            }

            private boolean isCharAllowed2(char c) {
                if(sb.length()==0)
                {
                      return Character.isLetter(c);
                }
                else
                {
                return (Character.isLetter(c)||Character.isDigit(c)||c=='_'||c=='.');
                }

            }

}; 

我只能输入字母。我认为问题就在这一行:

sb = new StringBuilder(end - start);

每次按下键时,都会创建一个新的Stringbuilder对象。因此,它的长度将为零,并且仅返回字母的第一个条件。

所以我想把stringbuilder设置成另一个变量。它部分工作但是当我按退格键并清除文本时,新变量的值也必须被清除。我该如何解决?

2 个答案:

答案 0 :(得分:0)

尝试使用textwatcher验证输入

每次用户输入或删除字符后,都会调用TextWatcher的方法afterTextChanged。您可以根据输入验证输入(在代码中给出),然后在用户输入无效字符时显示错误。

edittext.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) {
            String text = edittext.getText().toString();
            String len = text.length();

            if(Character.isDigit(text.charAt(0))){
                //First letter is a digit. Do something
                //Show an error
            }

            text.substring(1); //remove first character from string

            if(text.matches("^[a-zA-Z0-9_.]+$"){
                //contains invalid character (listed by you)
                //it contains a character among a-z, A-Z, 0-9, _ or .
                //show an error
            }

        }
    });

因此,如果您发现任何无效字符,您可以向用户显示错误并阻止他继续。

答案 1 :(得分:0)

文档中解释了InputFilter的用法:

  

当缓冲区要用源范围start ... end的新文本替换dest的范围dstart ... dend时,将调用此方法。返回您希望放置在那里的CharSequence,包括适当的空字符串,或null以接受原始替换。小心不要拒绝0长度替换,因为这是删除文本时发生的情况。还要注意,您不应尝试对此方法的dest进行任何更改;你可能只会检查它的背景。注意:如果source是Spanned或Spannable的实例,则应将源中的span对象复制到筛选结果(即非null返回值)中。 copySpansFrom(Spanned,int,int,Class,Spannable,int)可以方便使用。

因此,只需返回""即可阻止不需要的字符:

public class MyTextFilter implements InputFilter {

    @Override
    public CharSequence filter(CharSequence charSequence, int i, int i2, Spanned spanned, int i3, int i4) {

        // delete support
        if(charSequence.length() < 1){
            return null;
        }

        // allow only if replacement has valid pattern.
        if (i3 == 0) {
            return charSequence.toString().matches("\\d[\\w\\._\\d]?") ? null : "";
        } else {
            return charSequence.toString().matches("[\\w\\._\\d]?") ? null : "";
        }
    }
}

此外,在API 19之上,您可以使用Character.isAlphabetic()方法。