Symbol procentowy XML systemu Android

309

Mam tablicę ciągów, w których %używany jest symbol. Właściwy format do używania %to %. Kiedy mam ciąg w tej tablicy z wielokrotnością %, daje mi ten błąd.

 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
zaid
źródło
6
Czy możesz opublikować kod XML, który powoduje ten błąd? Zidentyfikowanie problemu może być bardzo trudne bez dostrzeżenia przyczyny.
Chris Cashwell,
jest to błąd, który można łatwo odtworzyć dowolnym ciągiem zawierającym 2 lub więcej symboli%.
zaid
Jeśli nie szukasz celu formatowania, lepszy sposób na osiągnięcie tego.
Shishir Gupta
W moim przypadku błędnie wpisałem parametr formatowania jako 1% $ s, zamiast% 1 $ s.
Ashokchakravarthi Nagarajan

Odpowiedzi:

467

Android Asset Packaging Tool ( aapt) stał się bardzo rygorystyczny w najnowszej wersji i jest teraz używany we wszystkich wersjach Androida. Generowany błąd aapt jest generowany, ponieważ nie pozwala już na specyfikatory formatu pozycyjnego .

Oto kilka pomysłów, jak włączyć% -symbol do ciągów zasobów.

Jeśli nie potrzebujesz żadnych specyfikatorów formatu ani podstawień w swoim ciągu, możesz po prostu skorzystać z formattedatrybutu i ustawić go na false:

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

W takim przypadku ciąg nie jest używany jako ciąg formatujący, Formatterwięc nie musisz uciekać od% -symbols. Wynikowy ciąg to „% a +% a == 2% a”.

Jeśli pominiesz formatted="false"atrybut, ciąg zostanie użyty jako ciąg formatujący i musisz uciec od symboli% -symbol. Robi się to poprawnie z podwójnym%:

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

Teraz nie aaptdaje żadnych błędów, ale w zależności od tego, jak go używasz, wynikowy ciąg może być „%% a + %% a == 2 %% a”, jeśli a Formatterjest wywoływany bez żadnych argumentów formatu :

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"

Bez kodu XML i kodu trudno jest powiedzieć, na czym dokładnie polega problem, ale mam nadzieję, że pomoże to nieco lepiej zrozumieć mechanizmy.

Josef Pfleger
źródło
1
wybrałem to jako odpowiedź, ponieważ powinno działać, ale najwyraźniej napotkałem błąd, który napotyka ten ciąg, więc zdecydowałem się użyć %% i „XXX.replaceAll („ %% ”,„% ”);”
zaid
4
użycie sformatowanego = fałsz działa dobrze. Tak to wykorzystałem: <string name = "information_description" formatted = "false"> \ 'Sweet \' 10% do 20%, nawet 35% masy cukru </entry>
Ktoś gdzieś
1
sformatowane = fałsz również działa dla mnie ładnie. Używając %%, dosłownie pojawił się jako %% na moim urządzeniu i emulatorze.
samwize
sformatowany = fałsz działał w przeszłości dla mnie dobrze. teraz (ADT 22), z jakiegoś powodu tak nie jest. a jeśli użyję: „str = mContext.getString (R.string.str,„ hello ”)”, zostanie wyświetlone ostrzeżenie o strzępie: „Łańcuch formatu„ str ”nie jest prawidłowym łańcuchem formatu, więc nie należy go przekazywać do String.format ”
programista Androida
1
Jeśli uzyskujesz dostęp z <string-array />, to do drukowania wartości procentowej użyj \ u0025. To zadziałało dla mnie.
Chintan Shah
157

Aby zezwolić aplikacji na używanie sformatowanych ciągów znaków z zasobów, należy poprawić plik XML. Na przykład

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

należy zastąpić

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

Widać to na szczegóły.

Paul E.
źródło
2
Dzięki, podałeś brakujący link - dosłownie.
akauppi
22
W przypadku wielokrotnego podstawienia parametrów (na przykład z łańcuchów), stosowania %1$s, %2$sitp
CJBS
1
kto przeczyta tak wielką odpowiedź na tę małą rzecz? Dzięki, przewijam w dół, by cię znaleźć.
Janaka R Rajapaksha
73

Możesz uciec% używając %% dla parsera XML, ale jest pokazany dwukrotnie w urządzeniu.

Aby wyświetlić go raz, spróbuj użyć następującego formatu: \%%

Na przykład

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

jest pokazany jak Fat Burning (50% to 60%)w urządzeniu

pavblazek
źródło
6
\ %% powoduje awarie w Nexusie 4 4.2.1. Nie testowałem innych.
Jon Willis
Działa to dobrze i jest łatwe, gdy znasz już procent, który chcesz uwzględnić w swoich ciągach, w porównaniu do korzystania z formatera ciągów i zawsze musisz programowo ustawiać te zapisane na stałe wartości.
portfoliobuilder
U mnie też to się zawiesiło na Nexusie 5.1.1. @ViliusK odpowiedź jest poprawna.
Chan Jing Hong
2
wystarczy użyć %% zamiast%
Sundeep1501
37

Posługiwać się

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

dostać

80% wins jako sformatowany ciąg.

Używam String.format()metody, aby wstawić numer zamiast %d.

ViliusK
źródło
12

W pliku strings.xml możesz użyć dowolnego znaku Unicode.

Na przykład numer Unicode dla znaku procentu to 0025:

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

Pełną listę znaków Unicode można znaleźć tutaj

Asaf Pinhassi
źródło
1
To nie ma sensu. & # x0025; i% są identyczne w pliku xml.
BeniBela,
Plik zasobów jest konwertowany na zasób Java, a tym samym %znak wraca. Obawiam się, że to nie rozwiązuje problemu.
Paul Lammertsma
9

aby uciec od symbolu procentu, wystarczy %%

na przykład :

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

zwraca „10%”

landerlyoung
źródło
1
Twoja odpowiedź jest prawie taka sama jak kilka innych istniejących odpowiedzi
Ben Rhys-Lewis,
... i źle, bo 10%nie zwraca %10. FIY: Kiedy używasz String.format, powinieneś zawsze określać ustawienia regionalne. Możesz być naprawdę zaskoczony, gdy nie umieścisz ustawień regionalnych i nie użyjesz ustawień regionalnych arabskich dla numerów formatów ...
mtrakal
7

Nie do końca twój problem, ale podobny.

Jeśli masz więcej niż jedno formatowanie we wpisie ciągu, nie powinieneś używać „% s” wiele razy.

NIE:

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

ROBIĆ :

<string name="entry">Planned time %1$s - %2$s (%3$s)</string>
Garytech
źródło
5

Możesz uciec% w xml za pomocą %%, ale musisz ustawić tekst w kodzie, a nie w układzie xml.

Mee
źródło
1
Tak, ucieka z podwójnym% i ładnie się kompiluje. Ale kiedy działa na emulatorze, a nawet urządzeniach, może być wyświetlany jako %%.
samwize
5

Może to być przypadek zbyt ścisłego IDE.

Pomysł jest zdrowy, ogólnie rzecz biorąc, powinieneś określić kolejność zmiennych podstawiania, aby w przypadku dodania zasobów dla innego języka kod Java nie musiał być zmieniany. Istnieją jednak dwa problemy z tym:

Po pierwsze, ciąg taki jak:

You will need %.5G %s

do zastosowania, ponieważ będziesz potrzebować 2.1200 mg będzie miał taką samą kolejność w dowolnym języku, ponieważ ta ilość masy jest zawsze naukowo reprezentowana w tej kolejności.

Po drugie, jeśli ustawisz kolejność zmiennych w jakimkolwiek języku, w którym określone są domyślne zasoby (np. Angielski), wystarczy określić pozycje w łańcuchach zasobów dla języków, używając innej kolejności niż domyślny język.

Dobra wiadomość jest taka, że ​​można to łatwo naprawić. Chociaż nie ma potrzeby określania pozycji, a IDE jest zbyt surowe, po prostu określ je. W powyższym przykładzie użyj:

Będziesz potrzebować% 1 $ .5G% 2 $ s

Steve Waring
źródło
4

Podstępna metoda: użycie małego znaku procentu, jak poniżej

 <string name="zone_50">Fat Burning (50&#65130; to 60&#65130;)</string> 

Znak procentu na Wikipedii

Bao Le
źródło
3

Spróbuj tego (po prawej):

<string name="content" formatted="false">Great application %s  ☞  %s  ☞  %s \\n\\nGo to download this application %s</string>
sonida
źródło
-1

Załóżmy, że chcesz pokazać (50% TANIEJ) i wpisać 50 w czasie wykonywania. Oto kod:

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

W klasie java użyj tego kodu:

String formattedString=String.format(context.getString(R.string.format_discount),discountString,"%");
holder1.mTextViewDiscount.setText(formattedString);
Harish Rana
źródło
-16

Spróbuj użyć ukośnika odwrotnego przed nim, jak poniżej:

\%
lolraccoon
źródło
To rozwiązanie prowadzi do awarii.
Prinkal Kumar