Это старая ветка, но у всех намеченных решений есть проблемы (в зависимости от устройства / версии Android / клавиатуры).
РАЗЛИЧНЫЙ ПОДХОД
Так что в конце концов япошел с другим подходом, вместо использования проблемной реализации InputFilter
, я использую TextWatcher
и TextChangedListener
EditText
.
ПОЛНЫЙ КОД (ПРИМЕР)
editText.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable editable) {
super.afterTextChanged(editable);
String originalText = editable.toString();
int originalTextLength = originalText.length();
int currentSelection = editText.getSelectionStart();
// Create the filtered text
StringBuilder sb = new StringBuilder();
boolean hasChanged = false;
for (int i = 0; i < originalTextLength; i++) {
char currentChar = originalText.charAt(i);
if (isAllowed(currentChar)) {
sb.append(currentChar);
} else {
hasChanged = true;
if (currentSelection >= i) {
currentSelection--;
}
}
}
// If we filtered something, update the text and the cursor location
if (hasChanged) {
String newText = sb.toString();
editText.setText(newText);
editText.setSelection(currentSelection);
}
}
private boolean isAllowed(char c) {
// TODO: Add the filter logic here
return Character.isLetter(c) || Character.isSpaceChar(c);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// Do Nothing
}
@Override
onTextChanged(CharSequence s, int start, int before, int count) {
// Do Nothing
}
});
Причина, по которой InputFilter
не является хорошим решением в Android, заключается в том, что он зависит от реализации клавиатуры.Ввод с клавиатуры фильтруется перед тем, как ввод передается в EditText
.Но поскольку некоторые клавиатуры имеют разные реализации для вызова InputFilter.filter()
, это проблематично.
С другой стороны, TextWatcher
не заботится о реализации клавиатуры, это позволяет нам создать простое решение иуверен, что он будет работать на всех устройствах.