Подтвердить что ты не робот

Android TextView: "Не конкатенировать текст, отображаемый с помощью setText"

Я устанавливаю текст с помощью setText() следующим образом.

prodNameView.setText("" + name);

prodOriginalPriceView.setText("" + String.format(getString(R.string.string_product_rate_with_ruppe_sign), "" + new BigDecimal(price).setScale(2, RoundingMode.UP)));

В этом первом простом использовании, а втором задается текст с форматированием текста.

Студия Android настолько интересна, что я использовал Меню Analyze -> Code Cleanup, и я получил предложение в двух строчках, например.

enter image description here

Не объединяйте текст, отображаемый с помощью setText. Использовать строку ресурса с заполнителями. меньше... (Ctrl + F1)

При вызове TextView # setText:

  • Никогда не вызывайте Number # toString() для форматирования чисел; он не будет правильно обрабатывать разделители дроби и специфичные для локали цифры. Рассмотреть возможность используя формат String # с правильными спецификациями формата (% d или% f) вместо.
  • Не передавайте строковый литерал (например, "Hello") для отображения текста. Закодированный текст не может быть должным образом переведен на другие языки. Попробуйте вместо этого использовать строки ресурсов Android.
  • Не создавайте сообщения, объединяя текстовые блоки. Такие сообщения не могут быть должным образом переведены.

Что я могу сделать для этого? Кто-нибудь может помочь объяснить, что это за штука и что мне делать?

4b9b3361

Ответ 1

В ресурсе есть перегруженная версия getString, которая принимает varargs типа Object: getString (int, java.lang.Object...), Если вы правильно настроили свою строку в файле strings.xml с правильными держателями мест, вы можете использовать эту версию для получения форматированной версии вашей последней строки. Например.

<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>

с помощью getString(R.string.welcome_message, "Test", 0);

android вернет строку с

 Hello Test! you have 0 new messages

О setText("" + name);

Ваш первый пример prodNameView.setText("" + name); не имеет для меня никакого смысла. TextView способен обрабатывать нулевые значения. Если имя равно null, текст не будет нарисован.

Ответ 2

Не путайте с % 1 $ s и % 2 $ d в принятом ответе. Вот несколько дополнительных сведений.

  • Спецификаторы формата могут иметь следующий синтаксис:

%[argument_index$]format_specifier

  1. Необязательный arguments_index указывается как число, заканчивающееся символом "$" после "%", и выбирает указанный аргумент в списке аргументов. На первый аргумент ссылается "1 $", на второй - "2 $" и т.д.
  2. Обязательный спецификатор формата - это символ, указывающий, как должен форматироваться аргумент. Набор действительных преобразований для данного аргумента зависит от типа данных аргумента .

Пример

Мы создадим следующую отформатированную строку, где серые части будут вставлены программно.

Привет Test! у вас есть 0 новые сообщения

Ваш string resource:

< string name="welcome_messages">Hello, %1$s! You have %2$d new messages

Сделайте string substitution как указано ниже:

getString(R.string.welcome_message, "Test", 0);

Примечание:

  • % 1 $ s будет заменен строкой "Test"
  • % 2 $ d будет заменено строкой "0"

Ответ 3

Я столкнулся с тем же сообщением об ошибке lint и решил его таким образом.

Первоначально мой код был:

private void displayQuantity(int quantity) {
    TextView quantityTextView = (TextView) findViewById(R.id.quantity_text_view);
    quantityTextView.setText("" + quantity);
}

Я получил следующую ошибку

Do not concatenate text displayed with setText. Use resource string with placeholders.

Итак, я добавил это в strings.xml

<string name="blank">%d</string>

Какой мой начальный "" + заполнитель для моего номера (количества).

Примечание: Моя переменная quantity была ранее определена и это то, что я хотел добавить в строку. Мой код в результате был

private void displayQuantity(int quantity) {
    TextView quantityTextView = (TextView) findViewById(R.id.quantity_text_view);
    quantityTextView.setText(getString(R.string.blank, quantity));
}

После этого моя ошибка ушла. Поведение в приложении не изменилось, и мое количество продолжало отображаться так, как я хотел, без ошибок.

Ответ 4

Не объединяйте текст внутри вашего метода setText(), объединяйте все, что вам нужно, в String и помещайте это значение String в свой метод setText().

пример: правильный путь

int min = 120;
int sec = 200;
int hrs = 2;

String minutes = String.format("%02d", mins);
            String seconds = String.format("%02d", secs);
            String newTime = hrs+":"+minutes+":"+seconds;

text.setText(minutes);

Не объединяйте внутри setText() как

text.setText(hrs+":"+String.format("%02d", mins)+":"+String.format("%02d", secs));

Ответ 5

Вы должны проверить этот поток и использовать заполнитель, подобный его (не проверен)

<string name="string_product_rate_with_ruppe_sign">Price : %1$d</string>

String text = String.format(getString(R.string.string_product_rate_with_ruppe_sign),new BigDecimal(price).setScale(2, RoundingMode.UP));
prodOriginalPriceView.setText(text);

Ответ 6

проблема заключается в том, что вы добавляете "" в начале каждой строки.

lint будет проверять аргументы, передаваемые на setText, и будет генерировать предупреждения, в вашем случае следующее предупреждение следующее:

Не создавать сообщения объединяя текстовые фрагменты. Такие сообщения не могут быть должным образом в переводе.

поскольку вы объединяете каждую строку с помощью "".

удалите эту конкатенацию, поскольку аргументы, которые вы передаете, уже являются текстами. Кроме того, вы можете использовать .toString(), если вообще не требуется нигде вместо того, чтобы конкатенировать вашу строку с помощью ""

Ответ 7

Если вам не нужна поддержка i18n, отключите эту проверку в Android Studio

Файл → Настройки → Редактор → Проверки → Android → Lint → Интернационализация TextView (снимите этот флажок)