如何在editText中将字母大写?

How to capitalize letters in 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);
            }
        }

当我将经过验证的数据设置回 edittext 时,无限循环开始,因为它再次调用方法 ontextCahnged()。所以我的目标是动态更改输入字母,我必须将其大写。我知道有更多最简单的方法可以做到这一点。但我需要通过这种方式。

有很多方法可以做到这一点:

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- 来自 apache Common

图书馆:http://commons.apache.org/proper/commons-lang/

WordUtils.capitalize(java.lang.String)

现在您可以将该字符串分配给您的输入框。

您可以将(EditText 的)输入类型设置为TYPE_CLASS_TEXT | TYPE_TEXT_FLAG_CAP_CHARACTERS.

在您的 EditText 上设置 android:inputType="textCapSentences"。

你可以关注这个linkhttps://developer.android.com/reference/android/text/InputFilter.AllCaps

您可以使用以下InputFilter.AllCaps

或这个

android:inputType="textCapCharacters"

为什么不使用标志?我通过添加 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);
            }
        }

您的问题出在 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。

有关详细信息,请阅读 How can I change the EditText text without triggering the Text Watcher?

你可以简单地使用 in XML

android:inputType="textCapCharacters"

无需编写大写字母代码。

这样试试:

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

if (hasChanged) {
            String newText = sb.toString().toUpperCase();
            textHeading.setText(newText);
            textHeading.setSelection(currentSelection);
        }