0

i have simple Edittext and when I'm going to change input letters in im setting listener new textWatcher and it's onTextChanged() method like:

@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);
            }
        }

endless cycle begins when i'm setting validated data back to the edittext becouse it calls method ontextCahnged() again. so my goal is dynamically change input letters and i have to capitalize it. I know there is more the easiest way to do it. but i need to do by this way.

7 Answers7

0

There is many ways to do that:

1- Using common Utils

Library: http://commons.apache.org/proper/commons-lang/

StringUtils.capitalize(..)

2- By Custom method

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- From apache Common

Library: http://commons.apache.org/proper/commons-lang/

WordUtils.capitalize(java.lang.String)

Now you can assign that string to your input box.

Irfan Nasim
  • 1,952
  • 2
  • 19
  • 29
0

You can set the input type (of EditText) to TYPE_CLASS_TEXT | TYPE_TEXT_FLAG_CAP_CHARACTERS.

OR

Set android:inputType="textCapSentences" on your EditText.

You can follow this link https://developer.android.com/reference/android/text/InputFilter.AllCaps

Ankita
  • 1,129
  • 1
  • 8
  • 15
0

You can use following InputFilter.AllCaps

or this

android:inputType="textCapCharacters"
Omkar
  • 13
  • 1
  • 2
0

Why not use a flag ? I've modified your code by adding a boolean setManually flag.

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);
            }
        }
Neeraj
  • 2,376
  • 2
  • 24
  • 41
0

You problem is with TextWatcher not with the logic what you are writing. Below Code block is causing the issue (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);
}

To handle this issue, you need to do below steps

  1. Remove Watcher from EditText
  2. Set text
  3. Add Watcher to EditText.

For more information read How can I change the EditText text without triggering the Text Watcher?

Pankaj Kumar
  • 81,967
  • 29
  • 167
  • 186
0

You can just simply use in XML

android:inputType="textCapCharacters"

no need to write code for capitlize letter.

Jigar Fumakiya
  • 2,039
  • 1
  • 8
  • 21
0

Try like this:

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

or

if (hasChanged) {
            String newText = sb.toString().toUpperCase();
            textHeading.setText(newText);
            textHeading.setSelection(currentSelection);
        }
Mani Vasagam
  • 820
  • 5
  • 10