Символ відсотків 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.
Ashokchakravarthi Nagarajan

Відповіді:


467

Інструмент упаковки Android Asset ( aapt) став дуже суворим в останньому випуску і зараз використовується для всіх версій Android. Помилка aapt, яку ви отримуєте, генерується, оскільки вона більше не дозволяє специфікатори формату не позиції .

Ось кілька ідей, як можна включити% -символ до рядків ресурсів.

Якщо вам не потрібні специфікатори формату або підстановки у рядку, ви можете просто скористатися formattedатрибутом і встановити його на false:

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

У цьому випадку рядок не використовується як рядок формату для Formatter тому вам не доведеться уникати своїх% -символів. Отриманий рядок "% a +% a == 2% a".

Якщо ви опустите formatted="false"атрибут, рядок використовується як рядок формату, і вам доведеться уникати символів% -symbols. Це правильно зроблено з подвійним%:

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

Тепер не aaptдає помилок, але залежно від того, яким чином ви його використовуєте, результуюча рядок може бути "%% a + %% a == 2 %% a", якщо виклик 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
я вибрав це як відповідь, тому що це повинно працювати, але, мабуть, є помилка, з якою вони стикаються з цією рядком, тому ive вирішив використовувати %% та "XXX.replaceAll (" %% ","% ");"
заїд

4
використання відформатованого = false працює добре. Ось як я це використав: <string name = "information_description" formatted = "false"> \ "Sweet \" 10% до 20%, навіть 35% цукру по вазі </string>
Хтось десь

1
відформатовано = false працює добре і для мене. Використовуючи %%, він буквально виявився як %% на моєму пристрої та емуляторі ..
samwize

відформатований = помилковий працював для мене чудово в минулому. зараз (ADT 22), чомусь це не так. і якщо я використовую: "str = mContext.getString (R.string.str," привіт ")", воно матиме таке попередження про підказку: "Формат рядка 'str' не є правильним рядком формату, тому його не слід передавати String.format "
андроїд розробник

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
Дякуємо, ви надали пропущене посилання - буквально.
акауппі

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

1
хто прочитає таку велику відповідь на цю дрібницю? Дякую, я прокручую вниз, щоб знайти вас.
Janaka R Раджапакша

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% OFF) і ввести 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.