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.
- Не создавайте сообщения, объединяя текстовые блоки. Такие сообщения не могут быть должным образом переведены.
Что я могу сделать для этого? Кто-нибудь может помочь объяснить, что это за штука и что мне делать?
Ответы
Ответ 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
- Необязательный arguments_index указывается как число, заканчивающееся символом "$" после "%", и выбирает указанный аргумент в списке аргументов. На первый аргумент ссылается "1 $", на второй - "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 (снимите этот флажок)