Динамическая строка с использованием String.xml?

Возможно ли иметь заполнители в строковых значениях в string.xml, которым могут присваиваться значения во время выполнения?

Пример:

некоторая строка PLACEHOLDER1 некоторая строка

Ответ 1

Форматирование и стилизация

Да, см. следующее из 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.

Ответ 2

Если вы хотите использовать параметр из фактического файла 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 файл, который им нужен.

Ответ 3

Дополнительный ответ

Когда я впервые увидел %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, если вы хотите его повторить.
  • Используйте %% для получения фактического символа %.
  • Подробнее читайте в следующем полезном учебнике: Android SDK Быстрый совет: форматирование строк ресурсов

Ответ 4

Ищет то же самое и, наконец, нашел следующее очень простое решение. Лучшее: это работает из коробки.
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. Работает на меня.:)

Ответ 6

Котлинская версия принятого ответа...

val res = resources
val text = String.format(res.getString(R.string.welcome_messages), username, mailCount)

Ответ 7

В 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))  

Вам может потребоваться получить ресурсы из контекста приложения.