【发布时间】:2012-06-03 06:11:08
【问题描述】:
我正在尝试实现一个 EditText,它将输入限制为仅限 alpha 字符 [A-Za-z]。
我从this post 开始使用 InputFilter 方法。当我键入“a%”时,文本会消失,然后如果我按退格键,则文本是“a”。我已经尝试过过滤器功能的其他变体,例如使用正则表达式仅匹配 [A-Za-z] 有时会看到重复字符等疯狂行为,我将输入“a”然后输入“b”然后得到“aab”输入“c”得到“aabaabc”,然后按退格键得到“aabaabcaabaabc”!
这是我目前使用的不同方法的代码。
EditText input = (EditText)findViewById( R.id.inputText );
InputFilter filter = new InputFilter() {
@Override
public CharSequence filter( CharSequence source, int start, int end, Spanned dest, int dstart, int dend ) {
//String data = source.toString();
//String ret = null;
/*
boolean isValid = data.matches( "[A-Za-z]" );
if( isValid ) {
ret = null;
}
else {
ret = data.replaceAll( "[@#$%^&*]", "" );
}
*/
/*
dest = new SpannableStringBuilder();
ret = data.replaceAll( "[@#$%^&*]", "" );
return ret;
*/
for( int i = start; i < end; i++ ) {
if( !Character.isLetter( source.charAt( i ) ) ) {
return "";
}
}
return null;
}
};
input.setFilters( new InputFilter[]{ filter } );
我完全被这个难住了,所以这里的任何帮助都将不胜感激。
编辑: 好的,我已经对 InputFilter 进行了很多实验并得出了一些结论,尽管没有解决问题。请参阅下面我的代码中的 cmets。我现在要试试 Imran Rana 的解决方案。
EditText input = (EditText)findViewById( R.id.inputText );
InputFilter filter = new InputFilter() {
// It is not clear what this function should return!
// Docs say return null to allow the new char(s) and return "" to disallow
// but the behavior when returning "" is inconsistent.
//
// The source parameter is a SpannableStringBuilder if 1 char is entered but it
// equals the whole string from the EditText.
// If more than one char is entered (as is the case with some keyboards that auto insert
// a space after certain chars) then the source param is a CharSequence and equals only
// the new chars.
@Override
public CharSequence filter( CharSequence source, int start, int end, Spanned dest, int dstart, int dend ) {
String data = source.toString().substring( start, end );
String retData = null;
boolean isValid = data.matches( "[A-Za-z]+" );
if( !isValid ) {
if( source instanceof SpannableStringBuilder ) {
// This works until the next char is evaluated then you get repeats
// (Enter "a" then "^" gives "a". Then enter "b" gives "aab")
retData = data.replaceAll( "[@#$%^&*']", "" );
// If I instead always returns an empty string here then the EditText is blanked.
// (Enter "a" then "^" gives "")
//retData = "";
}
else { // source is instanceof CharSequence
// We only get here if more than 1 char was entered (like "& ").
// And again, this works until the next char is evaluated then you get repeats
// (Enter "a" then "& " gives "a". Then enter "b" gives "aab")
retData = "";
}
}
return retData;
}
};
input.setFilters( new InputFilter[]{ filter } );
【问题讨论】:
-
带有
.replaceAll()的代码几乎是正确的。在String data = source.toString()中使用完整输入字符串创建字符串导致的重复字符,而您应该处理Android 询问的子集,如String data = source.toString().substring(start,end) -
似乎我在这里遇到的问题是,当我一次输入 1 个字符时,开始始终为 0。因此 String data = source.toString().substring( start, end );总是给我全文,而不仅仅是改变了什么。
-
...是的,刚刚尝试了来自 this post 的示例,并且 start 始终为 0,所以我也得到了重复的字符。
-
我尝试了所有其他解决方案并最终实现了它。看我的回答here