Как мне преобразовать строку в заголовок в Android?

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

16 ответов

Решение

Поместите это в свой класс текстовых утилит:

public static String toTitleCase(String str) {

    if (str == null) {
        return null;
    }

    boolean space = true;
    StringBuilder builder = new StringBuilder(str);
    final int len = builder.length();

    for (int i = 0; i < len; ++i) {
        char c = builder.charAt(i);
        if (space) {
            if (!Character.isWhitespace(c)) {
                // Convert to title case and switch out of whitespace mode.
                builder.setCharAt(i, Character.toTitleCase(c));
                space = false;
            }
        } else if (Character.isWhitespace(c)) {
            space = true;
        } else {
            builder.setCharAt(i, Character.toLowerCase(c));
        }
    }

    return builder.toString();
}

Вы ищете Apache's WordUtils.capitalize() метод.

Отсюда я получил несколько указателей: Android, в моем ListView нужно указывать первую букву каждого слова в верхнем регистре, но, в конце концов, я выбрал свое собственное решение (обратите внимание, этот подход предполагает, что все слова разделены одним пробелом, который было хорошо для моих нужд)

String[] words = input.getText().toString().split(" ");
StringBuilder sb = new StringBuilder();
if (words[0].length() > 0) {
    sb.append(Character.toUpperCase(words[0].charAt(0)) + words[0].subSequence(1, words[0].length()).toString().toLowerCase());
    for (int i = 1; i < words.length; i++) {
        sb.append(" ");
        sb.append(Character.toUpperCase(words[i].charAt(0)) + words[i].subSequence(1, words[i].length()).toString().toLowerCase());
    }
}
String titleCaseValue = sb.toString();

... где вход представляет собой представление EditText. Также полезно установить тип ввода в представлении, чтобы в любом случае по умолчанию использовался регистр заголовка:

input.setInputType(InputType.TYPE_TEXT_FLAG_CAP_WORDS);

Это помогает тебе

EditText view = (EditText) find..
String txt = view.getText();
txt = String.valueOf(txt.charAt(0)).toUpperCase() + txt.substring(1, txt.length());

В XML вы можете сделать это так:

android:inputType="textCapWords"

Проверьте ссылку на другие параметры, такие как регистр предложений, все заглавные буквы и т. Д. Здесь:

http://developer.android.com/reference/android/widget/TextView.html

Вот метод WordUtils.capitalize(), если вы не хотите импортировать весь класс.

public static String capitalize(String str) {
    return capitalize(str, null);
}

public static String capitalize(String str, char[] delimiters) {
    int delimLen = (delimiters == null ? -1 : delimiters.length);
    if (str == null || str.length() == 0 || delimLen == 0) {
        return str;
    }
    int strLen = str.length();
    StringBuffer buffer = new StringBuffer(strLen);
    boolean capitalizeNext = true;
    for (int i = 0; i < strLen; i++) {
        char ch = str.charAt(i);

        if (isDelimiter(ch, delimiters)) {
            buffer.append(ch);
            capitalizeNext = true;
        } else if (capitalizeNext) {
            buffer.append(Character.toTitleCase(ch));
            capitalizeNext = false;
        } else {
            buffer.append(ch);
        }
    }
    return buffer.toString();
}
private static boolean isDelimiter(char ch, char[] delimiters) {
    if (delimiters == null) {
        return Character.isWhitespace(ch);
    }
    for (int i = 0, isize = delimiters.length; i < isize; i++) {
        if (ch == delimiters[i]) {
            return true;
        }
    }
    return false;
}

Надеюсь, поможет.

У меня была такая же проблема, и я решил ее следующим образом:

import android.text.TextUtils;
...

String[] words = input.split("[.\\s]+");

for(int i = 0; i < words.length; i++) {
    words[i] = words[i].substring(0,1).toUpperCase()
               + words[i].substring(1).toLowerCase();
}

String titleCase = TextUtils.join(" ", words);

Обратите внимание, в моем случае мне нужно было также удалить периоды. Любые символы, которые должны быть заменены пробелами, могут быть вставлены между квадратными скобками во время "разделения". Например, следующее в конечном итоге заменит символы подчеркивания, точки, запятые или пробелы:

String[] words = input.split("[_.,\\s]+");

Это, конечно, может быть достигнуто гораздо проще с помощью символа "не слово":

String[] words = input.split("\\W+");

Стоит упомянуть, что числа и дефисы считаются "символами слова", поэтому эта последняя версия полностью соответствовала моим потребностям и, надеюсь, поможет кому-то еще.

Просто сделайте что-то вроде этого:

public static String toCamelCase(String s){
    if(s.length() == 0){
        return s;
    }
    String[] parts = s.split(" ");
    String camelCaseString = "";
    for (String part : parts){
        camelCaseString = camelCaseString + toProperCase(part) + " ";
    }
    return camelCaseString;
}

public static String toProperCase(String s) {
    return s.substring(0, 1).toUpperCase() +
            s.substring(1).toLowerCase();
}

Используйте эту функцию для преобразования данных в случае верблюда

 public static String camelCase(String stringToConvert) {
        if (TextUtils.isEmpty(stringToConvert))
            {return "";}
        return Character.toUpperCase(stringToConvert.charAt(0)) +
                stringToConvert.substring(1).toLowerCase();
    }

Kotlin - Android - Функция титульного кейса / верблюжьего кейса

fun toTitleCase(str: String?): String? {

        if (str == null) {
            return null
        }

        var space = true
        val builder = StringBuilder(str)
        val len = builder.length

        for (i in 0 until len) {
            val c = builder[i]
            if (space) {
                if (!Character.isWhitespace(c)) {
                    // Convert to title case and switch out of whitespace mode.
                    builder.setCharAt(i, Character.toTitleCase(c))
                    space = false
                }
            } else if (Character.isWhitespace(c)) {
                space = true
            } else {
                builder.setCharAt(i, Character.toLowerCase(c))
            }
        }

        return builder.toString()
    }

ИЛИ ЖЕ

fun camelCase(stringToConvert: String): String {
    if (TextUtils.isEmpty(stringToConvert)) {
        return "";
    }
    return Character.toUpperCase(stringToConvert[0]) +
            stringToConvert.substring(1).toLowerCase();
}

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

public static String toCamelCaseSentence(String s) {

    if (s != null) {
        String[] words = s.split(" ");

        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < words.length; i++) {
            sb.append(toCamelCaseWord(words[i]));
        }

        return sb.toString().trim();
    } else {
        return "";
    }
}

обрабатывает пустые строки (несколько пробелов в предложении) и однобуквенные слова в строке.

public static String toCamelCaseWord(String word) {
    if (word ==null){
        return "";
    }

    switch (word.length()) {
        case 0:
            return "";
        case 1:
            return word.toUpperCase(Locale.getDefault()) + " ";
        default:
            char firstLetter = Character.toUpperCase(word.charAt(0));
            return firstLetter + word.substring(1).toLowerCase(Locale.getDefault()) + " ";
    }
}

В Котлине это можно сделать так

      val value = "hey this is test word" // or{HEY THIS IS TEST WORD}
value.lowercase()
value.replaceFirstChar {
   if (it.isLowerCase()) {
     it.titlecase(Locale.getDefault())
   } else {
     it.toString()
   }
}
println(value)

Я написал код, основанный на методе Apache WordUtils.capitalize(). Вы можете установить разделители в виде строки регулярного выражения. Если вы хотите, чтобы слова типа "of" были пропущены, просто установите их в качестве разделителя.

public static String capitalize(String str, final String delimitersRegex) {
    if (str == null || str.length() == 0) {
        return "";
    }

    final Pattern delimPattern;
    if (delimitersRegex == null || delimitersRegex.length() == 0){
        delimPattern = Pattern.compile("\\W");
    }else {
        delimPattern = Pattern.compile(delimitersRegex);
    }

    final Matcher delimMatcher = delimPattern.matcher(str);
    boolean delimiterFound = delimMatcher.find();

    int delimeterStart = -1;
    if (delimiterFound){
        delimeterStart = delimMatcher.start();
    }

    final int strLen = str.length();
    final StringBuilder buffer = new StringBuilder(strLen);

    boolean capitalizeNext = true;
    for (int i = 0; i < strLen; i++) {
        if (delimiterFound && i == delimeterStart) {
            final int endIndex = delimMatcher.end();

            buffer.append( str.substring(i, endIndex) );
            i = endIndex;

            if( (delimiterFound = delimMatcher.find()) ){
                delimeterStart = delimMatcher.start();
            }

            capitalizeNext = true;
        } else {
            final char ch = str.charAt(i);

            if (capitalizeNext) {
                buffer.append(Character.toTitleCase(ch));
                capitalizeNext = false;
            } else {
                buffer.append(ch);
            }
        }
    }
    return buffer.toString();
}

Надеюсь, это поможет:)

В Котлине я сделал это легко вот так

yoursString.lowercase().replaceFirstChar { it.uppercase() }

Если вы ищете формат регистра заголовка, вам могут помочь функции расширения kotlin.

fun String.toTitleCase(): String {
if (isNotEmpty()) {
    val charArray = this.toCharArray()
    return buildString {
        for (i: Int in charArray.indices) {
            val c = charArray[i]
            // start find space from 1 because it can cause invalid index of position if (-1)
            val previous = if (i > 0) charArray[(i - 1)] else null
            // true if before is space char
            val isBeforeSpace = previous?.let { Character.isSpaceChar(it) } ?: false
            // append char to uppercase if current index is 0 or before is space
            if (i == 0 || isBeforeSpace) append(c.toUpperCase()) else append(c)
            print("char:$c, \ncharIndex: $i, \nisBeforeSpace: $isBeforeSpace\n\n")
        }
        print("result: $this")
    }
} return this }

И реализовать как

data class User(val name :String){ val displayName: String get() = name.toTitleCase() }

Пожалуйста, проверьте решение ниже, оно будет работать как для нескольких строк, так и для одной строки

 String toBeCapped = "i want this sentence capitalized";  
 String[] tokens = toBeCapped.split("\\s"); 

 if(tokens.length>0)
 {
   toBeCapped = ""; 

    for(int i = 0; i < tokens.length; i++)
    { 
     char capLetter = Character.toUpperCase(tokens[i].charAt(0)); 
     toBeCapped += " " + capLetter + tokens[i].substring(1, tokens[i].length()); 
    }
 }
 else
 {
  char capLetter = Character.toUpperCase(toBeCapped.charAt(0)); 
  toBeCapped += " " + capLetter + toBeCapped .substring(1, toBeCapped .length()); 
 }
Другие вопросы по тегам