EditText дублирует введённый текст при использовании InputFilter
При вводе или удалении символа текст дублируется, но не каждый раз, а через раз.
Под дебаггером вижу, что перед дублированием dstart=dend=dest.length, source содержит весь текст, который должен быть после изменения, start=0, end=source.length
Код фильтра:
class FileNameInputFilter implements InputFilter {
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
StringBuilder sb = new StringBuilder();
for (int i = start; i < end; i++) {
char ch = source.charAt(i);
if ("/\\:*?\"<>|".indexOf(ch) == -1) {
sb.append(ch);
}
}
return sb.toString();
}
}
Как это побороть?
Дополнение
Дублируется в пределах слова, строго через раз, вот так выглядит ввод "Hello World!":
HHelHHelloHHelHHello WWorWWorldWWorWWorld!
Цифры вводятся и удаляются нормально, глючат только буквы.
Ответы (2 шт):
Логика работы фильтра: если что-то не нравится - возвратить пустую строку, иначе null (оставить без изменения). Фактически проверка происходит посимвольно за исключением вставки из буфера.
EditText edit = new EditText( this );
setContentView( edit );
edit.setFilters( new InputFilter[]{
new InputFilter(){
@Override
public CharSequence filter( CharSequence source, int start, int end, Spanned spanned, int i2, int i3 ){
final String invalidChars = "/\\:*?\"<>|";
for( int i = start; i < end; i++ ){
if( invalidChars.indexOf( source.charAt( i ) ) != -1 ){
return "";
}
}
return null;
}
}
} );
Решение нашёл: нужно обязательно возвращать null если фильтр ничего не изменил. Но непонятно почему возврат эквивалентного текста ломает логику. Баг фреймворка?
Этом вариант работает почти как надо, за исключением того, что после ввода знаков пунктуации добавляются пробелы - они идут отдельным вызовом и поэтому я не знаю как их отфильтровать, не затрагивая введённые юзером намеренно.
class FileNameInputFilter implements InputFilter {
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
StringBuilder sb = new StringBuilder();
boolean changed = false;
for (int i = start; i < end; i++) {
char ch = source.charAt(i);
if ("/\\:*?\"<>|".indexOf(ch) == -1) {
sb.append(ch);
} else {
changed = true;
}
}
if (!changed) {
return null;
}
return sb;
}
}