Android XML Процент Символ


309

У меня есть массив строк, в которых используется %символ. Правильный формат для использования %ИС %. Когда у меня есть строка в этом массиве с несколькими, %это дает мне эту ошибку.

 Multiple annotations found at this
 line:
 - error: Multiple substitutions specified in non-positional format;
   did you mean to add the formatted="false" attribute?
 - error: Found tag </item> where </string-array> is expected

6
Можете ли вы опубликовать XML, который вызывает эту ошибку? Может быть очень трудно определить проблему, не видя ее причину.
Крис Кэшвелл

это ошибка, которая может быть легко воспроизведена любой строкой с 2 ​​или более символами%.
Заид

Если не ищите цель форматирования, лучший способ сделать это.
Шишир Гупта

В моем случае я ошибочно ввел параметр форматирования как 1% $ s вместо% 1 $ s.
Ашокчакраварти Нагараджан

Ответы:


467

Android Asset Packaging Tool ( aapt) стал очень строгим в своем последнем выпуске и теперь используется для всех версий Android. Получаемая вами aapt-ошибка генерируется, потому что она больше не допускает непозиционных спецификаторов формата .

Вот несколько идей, как вы можете включить% -символ в ваши строки ресурсов.

Если вам не нужны никакие спецификаторы формата или замены в вашей строке, вы можете просто использовать formattedатрибут и установить его в false:

<string formatted="false">%a + %a == 2%a</string>

В этом случае строка не используется в качестве строки форматирования, Formatterпоэтому вам не нужно экранировать ваши% -символы. В результате получается строка «% a +% a == 2% a».

Если вы пропустите formatted="false"атрибут, строка будет использоваться в качестве строки формата, и вы должны экранировать% -символы. Это правильно сделано с двойным%:

<string>%%a + %%a == 2%%a</string>

Теперь не aaptдает ошибок, но в зависимости от того, как вы его используете, результирующая строка может быть "%% a + %% a == 2 %% a", если Formatterвызывается без аргументов формата :

Resources res = context.getResources();

String s1 = res.getString(R.string.str);
// s1 == "%%a + %%a == 2%%a"

String s2 = res.getString(R.string.str, null);
// s2 == "%a + %a == 2%a"

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


1
я выбрал это как ответ, потому что он должен работать, но, очевидно, есть ошибка, с которой я сталкиваюсь с этой строкой, поэтому я решил использовать %% и "XXX.replaceAll (" %% ","% ");"
Заид

4
использование formatted = false работает хорошо. Вот как я это использовал: <string name = "information_description" formatted = "false"> \ 'Sweet \' от 10% до 20% и даже 35% сахара по весу </ string>
Кто-то где-то

1
formatted = false тоже хорошо работает для меня. Используя %%, он буквально показывался как %% на моем устройстве и эмуляторе.
samwize

отформатированный = false работал хорошо для меня в прошлом. сейчас (ADT 22), по какой-то причине это не так. и если я использую: "str = mContext.getString (R.string.str," hello ")", он получит следующее предупреждение: "Строка формата 'str' не является допустимой строкой формата, поэтому ее не следует передавать String.format "
Android-разработчик

1
Если вы обращаетесь к <string-array />, то для печати в процентах используйте \ u0025. Это сработало для меня.
Чинтан Шах

157

Чтобы приложение могло использовать отформатированные строки из ресурсов, вы должны исправить свой XML. Так, например

<string name="app_name">Your App name, ver.%d</string>

следует заменить на

<string name="app_name">Your App name, ver.%1$d</string>

Вы можете увидеть это для деталей.


2
Спасибо, вы предоставили недостающую ссылку - буквально.
akauppi

22
Для подстановки нескольких параметров (например, со строками) используйте %1$sи %2$sт. Д.
CJBS

1
кто будет читать такой большой ответ для этой мелочи? Спасибо, прокручиваю вниз, чтобы найти тебя.
Джанака Р Раджапакша

73

Вы можете избежать%, используя %% для XML-парсера, но он отображается дважды на устройстве.

Чтобы показать его один раз, попробуйте следующий формат: \%%

Например

<string name="zone_50">Fat Burning (50\%% to 60\%%)</string> 

отображается как Fat Burning (50% to 60%)на устройстве


6
\ %% вызывает сбои на Nexus 4 4.2.1. Не проверял других.
Джон Уиллис

Это работает хорошо и легко, когда вы уже знаете процент, который вы хотите включить в ваши строки, по сравнению с использованием средства форматирования строк и тем, что вам всегда приходится устанавливать эти жестко закодированные значения программно.
портфолио

Это разбилось и для меня на Nexus 5.1.1. @ViliusK ответ правильный.
Чан Цзин Хун

2
просто используйте %% вместо%
Sundeep1501

37

использование

<string name="win_percentage">%d%% wins</string>

получить

80% wins как отформатированная строка.

Я использую String.format()метод, чтобы получить номер вместо %d.


12

В вашем файле strings.xml вы можете использовать любой желаемый знак Unicode.

Например, номер Unicode для знака процента - 0025:

<string name="percent_sign">&#x0025;</string>

Вы можете увидеть полный список знаков Unicode здесь


1
В этом нет смысла. & # x0025; и% идентичны в XML-файле.
BeniBela

Файл ресурса преобразуется в ресурс Java, и при этом %символ возвращается. Боюсь, это не решит проблему.
Пол Ламмерцма

9

чтобы выйти из символа процента, вам просто нужно %%

например :

String.format("%1$d%%", 10)

возвращает "10%"


1
Ваш ответ в значительной степени совпадает с несколькими другими существующими ответами
Бен Рис-Льюис

... и неправильно, потому что 10%не возвращается %10. FIY: Когда вы используете, String.formatвы должны всегда указывать Locale. Вы можете быть действительно удивлены, когда вы не используете Locale и не используете арабский язык для форматирования чисел ...
mtrakal

7

Не совсем ваша проблема, но похожая.

Если у вас есть более одного форматирования в вашей строковой записи, вы не должны использовать «% s» несколько раз.

НЕ

<string name="entry">Planned time %s - %s (%s)</string>

ДЕЛАТЬ :

<string name="entry">Planned time %1$s - %2$s (%3$s)</string>

5

Вы можете избежать% в xml с помощью %%, но вам нужно установить текст в коде, а не в макете xml.


1
Да, он уходит с двойным% и хорошо компилируется. Но при запуске на эмуляторе или даже на устройствах он может отображаться как %%.
samwize

5

Это может быть в случае, если IDE станет слишком строгим.

Идея здравая, в общем, вы должны указать порядок переменных подстановки, чтобы при добавлении ресурсов для другого языка ваш код Java не нуждался в изменении. Однако есть две проблемы с этим:

Во-первых, строка, такая как:

You will need %.5G %s

для использования в качестве Вам потребуется 2.1200 мг будет иметь такой же порядок на любом языке, поскольку это количество массы всегда представлено в этом порядке с научной точки зрения.

Во-вторых, если вы установите порядок переменных на каком бы языке ни указывались ваши ресурсы по умолчанию (например, на английском языке), вам нужно только указать позиции в строках ресурсов для языков, которые используют порядок, отличный от языка по умолчанию.

Хорошей новостью является то, что это легко исправить. Даже если нет необходимости указывать позиции, а IDE слишком строг, просто все равно укажите их. Для примера выше используйте:

Вам понадобится% 1 $ .5G% 2 $ s



3

Попробуйте это (справа):

<string name="content" formatted="false">Great application %s  ☞  %s  ☞  %s \\n\\nGo to download this application %s</string>


-1

Предположим, вы хотите показать (скидка 50%) и ввести 50 во время выполнения. Вот код:

<string name="format_discount"> (
<xliff:g id="discount">%1$s</xliff:g>
<xliff:g id="percentage_sign">%2$s</xliff:g>
 OFF)</string>

В классе Java используйте этот код:

String formattedString=String.format(context.getString(R.string.format_discount),discountString,"%");
holder1.mTextViewDiscount.setText(formattedString);

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.