Возможно ли иметь заполнители в строковых значениях, string.xml
которым можно присваивать значения во время выполнения?
Пример:
немного строки PLACEHOLDER1 еще немного строки
Возможно ли иметь заполнители в строковых значениях, string.xml
которым можно присваивать значения во время выполнения?
Пример:
немного строки PLACEHOLDER1 еще немного строки
Ответы:
Да, см. Строковые ресурсы: форматирование и стилизация
Если вам нужно отформатировать строки, используя
String.format(String, Object...)
, то вы можете сделать это, поместив аргументы формата в строковый ресурс. Например, со следующим ресурсом:<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
В этом примере строка формата имеет два аргумента:
%1$s
является строкой и%2$d
является десятичным числом. Вы можете отформатировать строку с аргументами из вашего приложения следующим образом:Resources res = getResources(); String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);
Обратите внимание, что getString
есть перегрузка, которая использует строку в качестве строки формата:
String text = res.getString(R.string.welcome_messages, username, mailCount);
Если вам нужно обрабатывать множественное число, используйте это:
<plurals name="welcome_messages">
<item quantity="one">Hello, %1$s! You have a new message.</item>
<item quantity="other">Hello, %1$s! You have %2$d new messages.</item>
</plurals>
Первый mailCount
параметр используется, чтобы решить, какой формат использовать (одиночный или множественный), другие параметры - ваши замены:
Resources res = getResources();
String text = res.getQuantityString(R.plurals.welcome_messages, mailCount, username, mailCount);
См. Строковые ресурсы: множественное число для более подробной информации.
Когда я впервые увидел %1$s
и %2$d
в принятом ответе, это не имело смысла. Вот немного больше объяснений.
Они называются спецификаторами формата. В строке XML они находятся в виде
%[parameter_index$][format_type]
1$
, 2$
и 3$
. Порядок их размещения в строке ресурса не имеет значения, только порядок, в котором вы указываете параметры.тип формата : существует множество способов форматирования ( см. документацию ). Вот некоторые из них:
s
строкаd
десятичное целоеf
число с плавающей запятойМы создадим следующую отформатированную строку, где серые части вставляются программно.
Моя сестра
Mary
является12
лет.
string.xml
<string name="my_xml_string">My sister %1$s is %2$d years old.</string>
MyActivity.java
String myString = "Mary";
int myInt = 12;
String formatted = getString(R.string.my_xml_string, myString, myInt);
getString
потому что я был в деятельности. Ты можешь использоватьcontext.getResources().getString(...)
если он не доступен.String.format()
также отформатирует строку.1$
И 2$
условия не должны быть использованы в таком порядке. То есть 2$
может прийти раньше1$
. Это полезно при интернационализации приложения для языков, которые используют другой порядок слов.%1$s
несколько раз в xml, если хотите повторить его.%%
чтобы получить реальный %
характер.Если вы хотите использовать параметр из фактического файла strings.xml без использования кода Java:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE resources [
<!ENTITY appname "WhereDat">
<!ENTITY author "Oded">
]>
<resources>
<string name="app_name">&appname;</string>
<string name="description">The &appname; app was created by &author;</string>
</resources>
Это не работает для файлов ресурсов, т. Е. Переменные должны быть скопированы в каждый файл XML, который нуждается в них.
<!DOCTYPE... ]>
деталь в отдельном файле и включить ее в несколько файлов ресурсов? Любой трюк для достижения этого?
Искал то же самое и, наконец, нашел следующее очень простое решение. Лучше всего: это работает из коробки.
1. измените ваш ресурс строки:
<string name="welcome_messages">Hello, <xliff:g name="name">%s</xliff:g>! You have
<xliff:g name="count">%d</xliff:g> new messages.</string>
2. использовать подстановку строк:
c.getString(R.string.welcome_messages,name,count);
где c - это контекст, name - строковая переменная, и подсчитайте вашу переменную int
Вам нужно будет включить
<resources xmlns:xliff="http://schemas.android.com/apk/res-auto">
в вашем res / strings.xml. Работает для меня. :)
xliff
тегах вокруг спецификаторов формата? Какую дополнительную ценность они добавляют в отличие от простого использования спецификаторов %s
и %d
?
В Kotlin вам просто нужно установить строковое значение следующим образом:
<string name="song_number_and_title">"%1$d ~ %2$s"</string>
Создайте текстовое представление на вашем макете:
<TextView android:id="@+id/song_number_and_title"/>
Затем сделайте это в своем коде, если вы используете Anko:
val song = database.use { // get your song from the database }
song_number_and_title.setText(resources.getString(R.string.song_number_and_title, song.number, song.title))
Возможно, вам понадобится получить ресурсы из контекста приложения.
Тем не менее, вам также следует прочитать ответ Элиаса Мартенсона о том, что Android во множественном числе рассматривает «ноль» . Существует проблема с интерпретацией определенных значений, таких как «ноль».
в res / values / string.xml
<resources>
<string name="app_name">Hello World</string>
<string name="my_application">Application name: %s, package name: %s</string>
</resources>
в коде Java
String[] args = new String[2];
args[0] = context.getString(R.string.app_name);
args[1] = context.getPackageName();
String textMessage = context.getString(R.string.my_application,(Object[]) args);
Вы можете использовать MessageFormat
:
<string name="customer_address">Wellcome: {0} {1}</string>
В коде Java:
String text = MessageFormat(R.string.customer_address).format("Name","Family");
Уровень API 1:
https://developer.android.com/reference/java/text/MessageFormat.html
Если вы хотите написать процент (%), продублируйте его:
<string name="percent">%1$d%%</string>
label.text = getString(R.string.percent, 75) // Output: 75%.
Если вы пишете просто %1$d%
, вы получите сообщение об ошибке: Format string 'percent' is not a valid format string so it should not be passed to String.format
.
Да! Вы можете сделать это без написания кода Java / Kotlin, только XML, используя эту небольшую библиотеку, которую я создал, что делает это во время сборки, поэтому ваше приложение не будет затронуто: https://github.com/LikeTheSalad/android -string ссылка
Применение
Ваши строки:
<resources>
<string name="app_name">My App Name</string>
<string name="template_welcome_message">Welcome to ${app_name}</string>
</resources>
Сгенерированная строка после сборки:
<!--resolved.xml-->
<resources>
<string name="welcome_message">Welcome to My App Name</string>
</resources>
Прямое решение проблемы Kotlin:
strings.xml
<string name="customer_message">Hello, %1$s!\nYou have %2$d Products in your cart.</string>
kotlinActivityORFragmentFile.kt:
val username = "Andrew"
val products = 1000
val text: String = String.format(
resources.getString(R.string.customer_message), username, products )
В вашем строковом файле используйте это
<string name="redeem_point"> You currently have %s points(%s points = 1 %s)</string>
И в вашем коде используйте соответственно
coinsTextTV.setText(String.format(getContext().getString(R.string.redeem_point), rewardPoints.getReward_points()
, rewardPoints.getConversion_rate(), getString(R.string.rs)));
Котлин версия принятого ответа ...
val res = resources
val text = String.format(res.getString(R.string.welcome_messages), username, mailCount)
resources.getString(int, ... args)
метода с аргументами вместо String.format
. В этом коде также нет специфики kotlin, кроме val
ключевого слова. Смотрите ответ msbodw001