Я хочу ограничить символы только 0-9, a-z, A-Z и пробел. Установка типа ввода Я могу ограничить цифры, но я не могу понять, как InputFilter просматривает документы.
Как использовать InputFilter для ограничения символов в EditText в Android?
Ответ 1
Я нашел это на другом форуме. Работает как чемпион.
InputFilter filter = new InputFilter() {
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
for (int i = start; i < end; i++) {
if (!Character.isLetterOrDigit(source.charAt(i))) {
return "";
}
}
return null;
}
};
edit.setFilters(new InputFilter[] { filter });
Ответ 2
InputFilter
немного сложнее в версиях Android, которые отображают предложения словаря. Иногда вы получаете SpannableStringBuilder
, иногда просто String
в параметре source
.
Следующее InputFilter
должно работать. Не стесняйтесь улучшать этот код!
new InputFilter() {
@Override
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
if (source instanceof SpannableStringBuilder) {
SpannableStringBuilder sourceAsSpannableBuilder = (SpannableStringBuilder)source;
for (int i = end - 1; i >= start; i--) {
char currentChar = source.charAt(i);
if (!Character.isLetterOrDigit(currentChar) && !Character.isSpaceChar(currentChar)) {
sourceAsSpannableBuilder.delete(i, i+1);
}
}
return source;
} else {
StringBuilder filteredStringBuilder = new StringBuilder();
for (int i = start; i < end; i++) {
char currentChar = source.charAt(i);
if (Character.isLetterOrDigit(currentChar) || Character.isSpaceChar(currentChar)) {
filteredStringBuilder.append(currentChar);
}
}
return filteredStringBuilder.toString();
}
}
}
Ответ 3
намного проще:
<EditText
android:inputType="text"
android:digits="0,1,2,3,4,5,6,7,8,9,*,qwertzuiopasdfghjklyxcvbnm" />
Ответ 4
Ни один из опубликованных ответов не работал у меня. Я пришел со своим решением:
InputFilter filter = new InputFilter() {
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
boolean keepOriginal = true;
StringBuilder sb = new StringBuilder(end - start);
for (int i = start; i < end; i++) {
char c = source.charAt(i);
if (isCharAllowed(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 isCharAllowed(char c) {
return Character.isLetterOrDigit(c) || Character.isSpaceChar(c);
}
}
editText.setFilters(new InputFilter[] { filter });
Ответ 5
Используйте эту работу на 100% своей потребности и очень просто.
<EditText
android:inputType="textFilter"
android:digits="@string/myAlphaNumeric" />
В файле strings.xml
<string name="myAlphaNumeric">abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789</string>
Ответ 6
Чтобы избежать специальных символов в типе ввода
public static InputFilter filter = new InputFilter() {
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
String blockCharacterSet = "~#^|$%*[email protected]/()-'\":;,?{}=!$^';,?×÷<>{}€£¥₩%~`¤♡♥_|《》¡¿°•○●□■◇◆♧♣▲▼▶◀↑↓←→☆★▪:-);-):-D:-(:'(:O 1234567890";
if (source != null && blockCharacterSet.contains(("" + source))) {
return "";
}
return null;
}
};
Вы можете настроить фильтр на свой текст редактирования, как показано ниже
edtText.setFilters(new InputFilter[] { filter });
Ответ 7
В дополнение к принятому ответу также можно использовать, например: android:inputType="textCapCharacters"
, как атрибут <EditText>
, чтобы принимать только символы верхнего регистра (и числа).
Ответ 8
По какой-то причине конструктор класса android.text.LoginFilter является областью действия пакета, поэтому вы не можете напрямую его расширять (хотя он будет идентичен этому коду). Но вы можете расширить LoginFilter.UsernameFilterGeneric! Тогда у вас есть это:
class ABCFilter extends LoginFilter.UsernameFilterGeneric {
public UsernameFilter() {
super(false); // false prevents not-allowed characters from being appended
}
@Override
public boolean isAllowed(char c) {
if ('A' <= c && c <= 'C')
return true;
if ('a' <= c && c <= 'c')
return true;
return false;
}
}
Это действительно не документировано, но это часть основного lib, а источник является простым. Я использую его какое-то время, до сих пор никаких проблем, хотя я признаю, что не пробовал делать что-либо сложное с участием spannables.
Ответ 9
Правильно, лучший способ сделать это, чтобы исправить его в самом макете XML, используя:
<EditText
android:inputType="text"
android:digits="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" />
как правильно указал Флориан Фрелих, он хорошо работает и для текстовых просмотров.
<TextView
android:inputType="text"
android:digits="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" />
Просто предостережение, символы, указанные в android:digits
, будут отображаться только, поэтому будьте осторожны, чтобы не пропустить ни одного набора символов:)
Ответ 10
Это простое решение работало для меня, когда мне нужно было запретить пользователю вводить пустые строки в EditText. Вы можете, конечно, добавить больше символов:
InputFilter textFilter = new InputFilter() {
@Override
public CharSequence filter(CharSequence c, int arg1, int arg2,
Spanned arg3, int arg4, int arg5) {
StringBuilder sbText = new StringBuilder(c);
String text = sbText.toString();
if (text.contains(" ")) {
return "";
}
return c;
}
};
private void setTextFilter(EditText editText) {
editText.setFilters(new InputFilter[]{textFilter});
}
Ответ 11
Если вы подклассифицируете InputFilter, вы можете создать свой собственный InputFilter, который будет отфильтровывать любые не-буквенно-цифровые символы.
Интерфейс InputFilter имеет один метод, filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend)
, и он предоставляет вам всю информацию, необходимую для того, чтобы узнать, какие символы были введены в EditText, которому он назначен.
Как только вы создали свой собственный InputFilter, вы можете назначить его EditText, вызвав setFilters (...).
http://developer.android.com/reference/android/text/InputFilter.html#filter(java.lang.CharSequence, int, int, android.text.Spanned, int, int)
Ответ 12
Игнорируя информацию о пробелах, с которой другие люди справились, чтобы правильно обрабатывать предложения по словарю, я обнаружил, что работает следующий код.
Источник растет по мере того, как предложение растет, поэтому мы должны посмотреть, сколько персонажей он ожидает от нас, прежде чем мы что-нибудь вернем.
Если у нас нет никаких недопустимых символов, верните значение null, чтобы произошла замена по умолчанию.
В противном случае нам нужно вычесть действительные символы из подстроки, которые будут добавлены в файл EditText.
InputFilter filter = new InputFilter() {
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
boolean includesInvalidCharacter = false;
StringBuilder stringBuilder = new StringBuilder();
int destLength = dend - dstart + 1;
int adjustStart = source.length() - destLength;
for(int i=start ; i<end ; i++) {
char sourceChar = source.charAt(i);
if(Character.isLetterOrDigit(sourceChar)) {
if(i >= adjustStart)
stringBuilder.append(sourceChar);
} else
includesInvalidCharacter = true;
}
return includesInvalidCharacter ? stringBuilder : null;
}
};
Ответ 13
для предотвращения слов в edittext. создайте класс, который можно использовать в любое время.
public class Wordfilter implements InputFilter
{
@Override
public CharSequence filter(CharSequence source, int start, int end,Spanned dest, int dstart, int dend) {
// TODO Auto-generated method stub
boolean append = false;
String text = source.toString().substring(start, end);
StringBuilder str = new StringBuilder(dest.toString());
if(dstart == str.length())
{
append = true;
str.append(text);
}
else
str.replace(dstart, dend, text);
if(str.toString().contains("aaaaaaaaaaaa/*the word here*/aaaaaaaa"))
{
if(append==true)
return "";
else
return dest.subSequence(dstart, dend);
}
return null;
}
}
Ответ 14
Это старый поток, но все решения имеют проблемы (в зависимости от устройства/версии Android/Keyboard).
РАЗЛИЧНЫЙ ПОДХОД
Итак, в конце концов я пошел с другим подходом, вместо использования 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
не заботится о реализации клавиатуры, это позволяет нам создать простое решение и быть уверенным, что оно будет работать на всех устройствах.
Ответ 15
Можно использовать setOnKeyListener
. В этом методе мы можем настроить вход edittext
!
Ответ 16
если вы хотите включить пробел в свой ввод, а затем добавьте пробел в код android: digit, как показано выше.
Он отлично работает для меня даже в версии выше android 4.0.
наслаждайтесь:)