Ich versuche, die zu verwenden getQuantityString -Methode in den abzurufenden Ressourcen Menge Zeichenfolgen (Plural) basierend auf den Richtlinien für Android-Entwickler Mengenzeichenfolge (Plural)
Der Fehler, den ich bekomme, ist
Fehler: (604) Mehrere Ersetzungen in nicht-positionalem Format angegeben; Wollten Sie das Attribut formatted=”false” hinzufügen?
Fehler: (604) Tag gefunden, wo erwartet
wenn ich Plurale wie unten einrichte
<plurals name="productCount">
<item quantity="one" formatted="true">%1$d of %2$d product</item>
<item quantity="other" formatted="true">%1$d of %2$d products</item>
</plurals>
Und versuchen Sie es wie folgt zu lesen productIndexCountText.setText(getResources().getQuantityString(R.plurals.productCount, position, size));
Eine Problemumgehung besteht darin, die Zeichenfolge aufzuteilen, um den Plural nur für den letzten Teil der Zeichenfolge zu verwenden, und die beiden Teile zu verketten. Aber das versuche ich möglichst zu vermeiden.
Sie müssen das Attribut “formatiert” für keines dieser Elemente festlegen. Bei der Verwendung von Mengenstrings gibt es nur drei Möglichkeiten:
- Die Ressourcenzeichenfolge ist Klartext und enthält keine Parameter
- die Ressourcenzeichenfolge enthält nur einen Parameter (höchstwahrscheinlich die Menge); verwenden
%d
oder welches Format Sie benötigen
- die Ressourcenzeichenfolge enthält mehrere Parameter; auf alle Parameter muss beispielsweise explizit über ihre Position zugegriffen werden
%1$d
Wie für die getQuantityString
-Methode gibt es zwei Überladungen: eine mit nur der Ressourcen-ID und der Menge und eine mit einer zusätzlichen Object... formatArgs
Parameter.
Für Fall 1. können Sie die verwenden getQuantityString(@PluralsRes int id, int quantity)
Methode.
Für alle anderen Fälle, dh wenn Sie haben irgendein Parameter benötigen Sie die getQuantityString(@PluralsRes int id, int quantity, Object... formatArgs)
Überlast. Notiz: alle Parameter müssen im Parameterarray vorhanden sein. Das heißt, wenn der Ressourcen-String die Menge anzeigt, wird die Mengenvariable übergeben zweimal zur Funktion.
Das liegt daran, dass die quantity
Der Parameter der Methode selbst wird beim Auflösen der Positionsparameter Ihrer Ressourcenzeichenfolge nicht berücksichtigt.
Wenn dies also Ihre Ressourcen sind,
<resources>
<plurals name="test0">
<item quantity="one">Test ok</item>
<item quantity="other">Tests ok</item>
</plurals>
<plurals name="test1">
<item quantity="one">%d test ok</item>
<item quantity="other">%d tests ok</item>
</plurals>
<plurals name="test2">
<item quantity="one">%2$s: %1$d test ok</item>
<item quantity="other">%2$s: %1$d tests ok</item>
</plurals>
<plurals name="test3">
<item quantity="one">%3$s: %1$d test out of %2$d ok</item>
<item quantity="other">%3$s: %1$d tests out of %2$d ok</item>
</plurals>
</resources>
dann die entsprechenden anrufe getQuantityString
sind:
int success = 1;
int total = 10;
String group = "Group name";
getResources().getQuantityString(R.plurals.test0, success)
// Test ok
getResources().getQuantityString(R.plurals.test1, success, success)
// 1 test ok
getResources().getQuantityString(R.plurals.test2, success, success, group)
// Group name: 1 test ok
getResources().getQuantityString(R.plurals.test3, success, success, total, group)
// Group name: 1 test out of 10 ok
success = 5;
getResources().getQuantityString(R.plurals.test0, success)
// Tests ok
getResources().getQuantityString(R.plurals.test1, success, success)
// 5 tests ok
getResources().getQuantityString(R.plurals.test2, success, success, group)
// Group name: 5 tests ok
getResources().getQuantityString(R.plurals.test3, success, success, total, group)
// Group name: 5 tests out of 10 ok
Mengenklassen: Verständnis der quantity
Parameter
Wie oben erwähnt, ist der Schlüssel zu verstehen, dass die quantity
Parameter von getQuantityString
wird nicht verwendet, um die Platzhalter wie zu ersetzen %d
oder %1$d
. Stattdessen wird es verwendet, um das Angemessene zu bestimmen item
von dem plurals
selbst, in Kombination mit dem Gebietsschema der Ressourcendatei.
Beachten Sie jedoch, dass dies eine weniger direkte Zuordnung ist als der Name des Attributs und seine möglichen Werte (zero
, one
, two
, few
, many
, other
) könnte vorschlagen. Zum Beispiel die Bereitstellung einer zusätzlichen <item quantity="zero">
wird nicht funktionieren (zumindest nicht in Englisch), auch wenn der Wert der quantity
Parameter ist 0.
Der Grund dafür ist der Weg plurals
Arbeit in Android ist durch das Konzept von Mengenklassen. Eine Mengenklasse ist eine Menge von Mengenwerten, die in einer bestimmten Sprache dieselben grammatikalischen Regeln haben. Dies bedeutet entscheidend, dass
- welche Mengenklassen verwendet werden und
- welche numerischen Werte ihnen zugeordnet sind
ist abhängig vom Gebietsschema, für das die jeweilige Ressourcendatei bestimmt ist.
Es ist wichtig zu verstehen, dass beide Fragen nur durch entschieden werden grammatikalische Notwendigkeit. Hier sind einige Beispiele:
- Nur auf Chinesisch oder Koreanisch
other
verwendet, da sich Sätze in diesen Sprachen aufgrund der gegebenen Menge grammatikalisch nicht unterscheiden.
- Auf Englisch gibt es zwei Klassen:
one
für den Literalwert 1 und other
für alle anderen Werte einschließlich 0.
- Auf Irisch wird 1 abgebildet
one
2 zugeordnet ist two
3-6 ist few
7-10 ist many
0 und 11+ ist other
.
- Auf Slowenisch der Wert 1 und alle Werte Ende in 01 zugeordnet sind
one
(1, 101, 3001, …). 2 und Werte, die auf 02 enden, werden zugeordnet two
(2, 302, 1002, …). 3, 4 und Werte, die auf 03 oder 04 enden, werden zugeordnet few
(3, 4, 6004, …). Alles andere ist other
(0, 11, 48, 312, …).
- Auf Polnisch werden 5-19 und Werte, die auf 05-19 enden, zugeordnet
many
(5, 12, 216, 4711, …). Werte, die auf 2, 3 oder 4 enden, einschließlich 2-4 selbst, werden zugeordnet few
(3, 42, 103, 12035374, …). Dies berücksichtigt jedoch, dass 12, 13 und 14 Ausnahmen von dieser Regel sind, weil sie zugeordnet sind many
. (Nebenbemerkung: ja, grammatikalisch gesehen ist 5 viele während 12035374 ist wenig.)
- Armenisch ist wie Englisch, mit der Ausnahme, dass auch der Wert 0 abgebildet wird
one
, denn so funktioniert ihre Grammatik. An diesem Beispiel können Sie erkennen, dass die Mengenklasse one
stellt nicht einmal notwendigerweise nur einsige Zahlen dar.
Wie Sie sehen, kann es ziemlich kompliziert werden, die richtige Mengenklasse zu ermitteln. Deshalb getQuantityString
tut das schon für dich, basierend auf der quantity
-Parameter und das Gebietsschema der Ressourcendatei. Die Regeln, nach denen Android (meistens) spielt, sind in der definiert Sprachpluralregeln des Unicode Common Locale Data Repository. Daher stammen auch die Namen der Mengenklassen.
All dies bedeutet, dass der Satz von Mengenklassen, der zum Übersetzen einer beliebigen Mengenzeichenfolge benötigt wird, von Sprache zu Sprache unterschiedlich sein kann (Chinesisch braucht nur other
Englisch braucht one
und other
Irisch braucht alle aber zero
, etc.). Innerhalb einer Sprache jedoch alle plurals
sollten jeweils die gleiche Anzahl von Artikeln haben, die alle für diese bestimmte Sprache erforderlichen Mengenklassen abdecken.
Fazit
Ein Anruf bei getQuantityString
kann so verstanden werden:
int success = 5;
int total = 10;
String group = "Group name";
getResources().getQuantityString(R.plurals.test3, success, success, total, group)
// \_____________/ \_____/ \___________________/
// | | |
// id: used to get the plurals resource | |
// quantity: used to determine the appropriate quantity class |
// formatArgs: used to positionally replace the placeholders %1, %2 and %3
Das quantity
Der Wert des Parameters „5“ bedeutet „Verwendet“. item
wird derjenige mit der Mengenklasse sein other
aus chinesischen, koreanischen, englischen, slowenischen und armenischen Ressourcendateien, few
für Irisch und many
für Polnisch.
Es gibt zwei Sonderfälle, die ich auch kurz erwähnen möchte:
Nicht ganzzahlige Größen
Grundsätzlich hängt die gewählte Klasse wieder von sprachspezifischen Regeln ab. Es ist weder allgemeingültig, wie eine Klasse ausgewählt wird, noch garantiert, dass jede Klasse, die erforderlich ist, um alle Regeln für ganze Zahlen abzudecken, auch für alle Nicht-Ganzzahlen verwendet wird. Hier sind ein paar Beispiele:
- Für Englisch wird jeder Wert mit Dezimalstellen immer zugeordnet
other
.
- Für Slowenisch wird jeder Wert mit Dezimalstellen immer zugeordnet
few
.
- Für Irisch hängt die Wahl vom ganzzahligen Teil ab.
- Für Polnisch werden im Gegensatz zu den komplexen Regeln für ganze Zahlen immer Nicht-Ganzzahlen abgebildet
other
wie auf Englisch.
Notiz: So ist es sollte laut sein Sprachpluralregeln. Leider hat Android keine leicht verfügbare Methode für float
oder double
im Augenblick.
Mehrere Mengen in einer Zeichenfolge
Wenn Ihr Anzeigetext mehrere Mengen hat, z %d match(es) found in %d file(s).
teilen Sie es auf drei getrennte Ressourcen:
%d match(es)
(plurals
Artikel)
%d file(s)
(plurals
Artikel)
%1$s found in %2$s.
(gewöhnlich parametrisiert strings
Artikel)
Sie können dann die entsprechenden Anrufe tätigen getQuantityString
für 1 und 2, und dann noch eins zu getString
für die dritte, mit den ersten beiden leicht lokalisierten Saiten als formatArgs
.
Der Grund dafür ist, dass Übersetzer die Parameterreihenfolge in der dritten Ressource ändern können, falls die Sprache dies erfordert. ZB wenn die einzige gültige Syntax in einer hypothetischen Sprache war In %d file(s) it found %d match(es).
könnte der Übersetzer den Plural wie gewohnt übersetzen und dann die dritte Ressource als übersetzen In %2$s it found %1$s.
um die vertauschte Bestellung zu berücksichtigen.
Für andere, die nach ähnlichen Informationen suchen, finden Sie hier den offiziellen Leitfaden. developer.android.com/guide/topics/resources/…
– hjchin
16. Januar 2019 um 9:43 Uhr