Я пытаюсь реализовать EditText, который ограничивает ввод только альфа-символами [A-Za-z].
Я начал с метода InputFilter из этого сообщения. Когда я набираю "%", текст исчезает, и если я нахожусь в обратном пространстве, текст "a". Я пробовал другие варианты функции фильтра, такие как использование регулярного выражения, чтобы соответствовать только [A-Za-z], и иногда вижу сумасшедшее поведение, такое как повторяющиеся символы, я набираю "a", затем "b" и получаю "aab", затем введите "c" и получите "aabaabc", затем нажмите "backspace" и получите "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 } );
Я полностью зациклен на этом, поэтому любая помощь здесь будет очень признательна.
EDIT: Хорошо, я довольно много экспериментировал с InputFilter и сделал некоторые выводы, хотя и не решил проблему. См. Комментарии в моем коде ниже. Я сейчас попробую решение 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 } );