Как сделать буквы заглавными в editText?

у меня есть простой Edittext, и когда я собираюсь изменить входные буквы в im, устанавливающем прослушиватель new textWatcher, и это метод onTextChanged(), например:

@Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            Log.d("qwer", "onTextChanged: " + s + " " + start + " " + before + " " + count);

            String originalText = s.toString();
            int originalTextLength = originalText.length();
            int currentSelection = textHeading.getSelectionStart();

            StringBuilder sb = new StringBuilder();
            boolean hasChanged = false;
            for (int i = 0; i < originalTextLength; i++) {
                char currentChar = originalText.charAt(i);
                if (isAllowed(currentChar) && i < 21) {
                    sb.append(currentChar);
                } else {
                    hasChanged = true;
                    textHeading.setError("Please insert current letters");
                }
            }
            if (hasChanged) {
                String newText = sb.toString();
                textHeading.setText(capitalize(newText));
                textHeading.setSelection(currentSelection);
            }
        }

бесконечный цикл начинается, когда я устанавливаю проверенные данные обратно в текст редактирования, потому что он снова вызывает метод ontextCahnged(). поэтому моя цель - динамически изменять входные буквы, и я должен использовать их заглавными буквами. Я знаю, что есть более простой способ сделать это. но мне нужно сделать таким образом.


person Хамидилло Мамытов    schedule 05.07.2018    source источник
comment
моя цель - динамически изменять входные буквы?? можно поподробнее?   -  person Hemant Parmar    schedule 05.07.2018
comment
просто установите android:inputType="textCapSentences" в свой EditText в xml.   -  person Jitesh Prajapati    schedule 05.07.2018
comment
когда пользователь вводит буквы в текст редактирования, я должен перехватывать все входные буквы и динамически проверять их буква за буквой...   -  person Хамидилло Мамытов    schedule 05.07.2018


Ответы (7)


Ваша проблема связана с TextWatcher, а не с логикой того, что вы пишете. Блок кода ниже вызывает проблему (endless cycle begins when i'm setting validated data back to the edittext becouse it calls method ontextCahnged() again)

if (hasChanged) {
    String newText = sb.toString();
    textHeading.setText(capitalize(newText)); // <<<<<< This line is culprit which is calling Watcher's method again and again.
    textHeading.setSelection(currentSelection);
}

Чтобы решить эту проблему, вам необходимо выполнить следующие шаги

  1. Удалить наблюдателя из EditText
  2. Установить текст
  3. Добавьте Наблюдателя в EditText.

Для получения дополнительной информации прочитайте Как я могу изменить текст EditText без запуска Text Watcher?

person Pankaj Kumar    schedule 05.07.2018

Есть много способов сделать это:

1- Использование общих утилит

Библиотека: http://commons.apache.org/proper/commons-lang/

StringUtils.capitalize(..)

2- Пользовательским методом

public static String upperCaseFirst(String value) {

        // Convert String to char array.
        char[] array = value.toCharArray();
        // Modify first element in array.
        array[0] = Character.toUpperCase(array[0]);
        // Return string.
        return new String(array);
    }

3- Из общего апача

Библиотека: http://commons.apache.org/proper/commons-lang/

WordUtils.capitalize(java.lang.String)

Теперь вы можете назначить эту строку в поле ввода.

person Irfan Nasim    schedule 05.07.2018

Вы можете установить тип ввода (EditText) на TYPE_CLASS_TEXT | TYPE_TEXT_FLAG_CAP_CHARACTERS.

ИЛИ

Установите android:inputType="textCapSentences" в свой EditText.

Вы можете перейти по этой ссылке https://developer.android.com/reference/android/text/InputFilter.AllCaps

person Ankita    schedule 05.07.2018

Вы можете использовать следующий InputFilter.AllCaps

или это

android:inputType="textCapCharacters"
person Omkar    schedule 05.07.2018

Почему бы не использовать флаг? Я изменил ваш код, добавив флаг boolean setManually.

boolean setManually = false;
@Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            Log.d("qwer", "onTextChanged: " + s + " " + start + " " + before + " " + count);
            if (setManually) {
                 setManually = false;
                  return;
            }

            String originalText = s.toString();
            int originalTextLength = originalText.length();
            int currentSelection = textHeading.getSelectionStart();

            StringBuilder sb = new StringBuilder();
            boolean hasChanged = false;
            for (int i = 0; i < originalTextLength; i++) {
                char currentChar = originalText.charAt(i);
                if (isAllowed(currentChar) && i < 21) {
                    sb.append(currentChar);
                } else {
                    hasChanged = true;
                    textHeading.setError("Please insert current letters");
                }
            }
            if (hasChanged) {
                String newText = sb.toString();
                 setManually = true;
                textHeading.setText(capitalize(newText));
                textHeading.setSelection(currentSelection);
            }
        }
person Neeraj    schedule 05.07.2018

Вы можете просто использовать в XML

android:inputType="textCapCharacters"

нет необходимости писать код для заглавной буквы.

person Jigar Fumakiya    schedule 05.07.2018

Попробуйте так:

  String originalText = s.toString().toUpperCase();

or

if (hasChanged) {
            String newText = sb.toString().toUpperCase();
            textHeading.setText(newText);
            textHeading.setSelection(currentSelection);
        }
person Mani Vasagam    schedule 05.07.2018