Возможно ли иметь заполнители в строковых значениях в string.xml
, которым могут присваиваться значения во время выполнения?
Пример:
некоторая строка PLACEHOLDER1 некоторая строка
Возможно ли иметь заполнители в строковых значениях в string.xml
, которым могут присваиваться значения во время выполнения?
Пример:
некоторая строка PLACEHOLDER1 некоторая строка
Да, см. следующее из String Resources: форматирование и стилизация
Если вам нужно форматировать строки, используя
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);
Подробнее см. String Resources: Plurals.
Если вы хотите использовать параметр из фактического файла 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 файл, который им нужен.
Когда я впервые увидел %1$s
и %2$d
в принятом ответе, это не имело смысла. Вот немного больше объяснений.
Маркеры замещения формата строки в xml находятся в форме
%[parameter index]$[format type]
%1
, %2
и %3
. Заказ, который вы размещаете в строке ресурса, не имеет значения, только порядок, в котором вы указываете параметры в String.format
.тип формата. Существует множество способов форматирования (см. документацию). Вот некоторые общие:
$s
string$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
, потому что я был в Activity. Вы можете использовать context.getResources().getString(...)
, если он недоступен.String.format()
также форматирует строку.%1
и %2
не должны использоваться в этом порядке. То есть %2
может быть до %1
. Это полезно при интернационализации приложения для языков, которые используют другой порядок слов.%1$s
несколько раз в xml, если вы хотите его повторить.%%
для получения фактического символа %
.Ищет то же самое и, наконец, нашел следующее очень простое решение. Лучшее: это работает из коробки.
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 - это контекст, имя - строковая переменная и подсчитывает вашу переменную int
Вам нужно включить
<resources xmlns:xliff="http://schemas.android.com/apk/res-auto">
в файле res/strings.xml. Работает на меня.:)
Тем не менее, вы также должны прочитать Elias Mårtenson ответ на множественное использование Android "нуля" . Существует проблема с интерпретацией определенных значений, таких как "ноль".
Котлинская версия принятого ответа...
val res = resources
val text = String.format(res.getString(R.string.welcome_messages), username, mailCount)
В 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))
Вам может потребоваться получить ресурсы из контекста приложения.
Вы можете использовать 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