您不需要为任何这些项目设置“格式化”属性。使用数量字符串时,只有三种可能:
- 资源字符串是纯文本,不包含任何参数
- 资源字符串只包含一个参数(很可能是数量);使用
%d
或您需要的任何格式
- 资源字符串包含多个参数;所有参数都必须通过它们的位置显式访问,例如
%1$d
至于getQuantityString
方法,有两种重载:一种只有资源id和数量,另一种是附加Object... formatArgs
参数。
对于案例 1.,您可以使用该getQuantityString(@PluralsRes int id, int quantity)
方法。
对于所有其他情况,即如果您有任何参数,则需要getQuantityString(@PluralsRes int id, int quantity, Object... formatArgs)
重载。注意:所有参数都必须存在于参数数组中。这意味着,如果资源字符串显示数量,数量变量将两次传递给函数。
那是因为quantity
在解析资源字符串的位置参数时不考虑方法本身的参数。
所以如果这些是你的资源,
<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>
那么适当的调用getQuantityString
是:
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
数量类:理解quantity
参数
如上所述,关键是要了解quantity
参数 ofgetQuantityString
不是用来代替%d
or之类的占位符%1$d
。相反,它用于item
从plurals
自身确定合适的,并结合资源文件的语言环境。
但请注意,与属性名称及其可能值 ( zero
, one
, two
, few
, many
, other
) 可能暗示的相比,这是一个不太直接的映射。例如,即使参数的值为 0 ,也<item quantity="zero">
无法提供附加功能(至少不是英文) 。quantity
原因是plurals
Android中的工作方式是通过数量类的概念。数量类是在给定语言中具有相同语法规则的一组数量值。这至关重要地意味着
取决于相应资源文件的语言环境。
重要的是要了解这两个问题仅由语法必要性决定。这里有些例子:
- 在中文或韩文中,
other
使用 only,因为在这些语言中,句子不会根据给定的数量在语法上有所不同。
- 在英语中,有两个类:
one
用于字面值 1,以及other
用于包括 0 在内的所有其他值。
- 在爱尔兰语中,1 映射到
one
,2 映射到two
,3-6 是few
,7-10 是many
,0 和 11+ 是other
。
- 在斯洛文尼亚语中,值 1和所有以 01结尾的值都映射到
one
(1, 101, 3001, ...)。2 和以 02 结尾的值映射到two
(2, 302, 1002, ...)。3, 4 和以 03 或 04 结尾的值映射到few
(3, 4, 6004, ...)。其他的都是other
(0, 11, 48, 312, ...)。
- 在波兰语中,5-19 和以 05-19 结尾的值映射到
many
(5, 12, 216, 4711, ...)。以 2、3 或 4 结尾的值(包括 2-4 本身)映射到few
(3, 42, 103, 12035374, ...)。然而,这尊重 12、13 和 14 是该规则的例外,因为它们被映射到many
. (旁注:是的,从语法上讲,5很多,而 12035374很少。)
- 亚美尼亚语就像英语,除了值 0 也映射到
one
,因为这就是他们的语法工作方式。你可以从这个例子中看到,数量类one
甚至不一定只代表一个数字。
如您所见,确定正确的数量类别可能会变得相当复杂。这就是为什么getQuantityString
已经根据quantity
参数和资源文件的语言环境为您执行此操作的原因。Android(主要)使用的规则在Unicode Common Locale Data Repository的Language Plural Rules中定义。这也是数量类名称的来源。
这意味着翻译任何数量字符串所需的数量类集可能因语言而异(中文只需要other
,英语需要one
和other
,爱尔兰语只需要zero
,等等)。然而,在一种语言中,plurals
每个人都应该有相同数量的项目,涵盖该特定语言所需的所有数量类别。
结论
调用getQuantityString
可以这样理解:
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
quantity
参数值“5”表示使用的将item
是具有other
中文、韩语、英语、斯洛文尼亚语和亚美尼亚语资源文件、few
爱尔兰语和many
波兰语的数量类的那个。
我还要简要提及两种特殊情况:
非整数数量
基本上,选择的类再次取决于特定于语言的规则。如何选择一个类既不是通用的,也不能保证覆盖所有整数规则所需的任何类也可用于任何非整数。这里有一些例子:
- 对于英语,任何带小数的值都将始终映射到
other
.
- 对于斯洛文尼亚语,任何带小数的值将始终映射到
few
.
- 对于爱尔兰语,选择取决于整数部分。
- 对于波兰语,与整数的复杂规则相比,非整数总是映射到
other
英语中的 like。
注意:这是根据语言复数规则应该是这样的。唉,Android 目前没有现成的方法。float
double
一个字符串中的多个数量
如果您的显示文本有多个数量,例如%d match(es) found in %d file(s).
,将其拆分为三个单独的资源:
%d match(es)
(plurals
项目)
%d file(s)
(plurals
项目)
%1$s found in %2$s.
(普通参数化strings
项)
然后,您可以对 1 和 2 进行适当的调用,然后对第三个getQuantityString
进行另一个调用,前两个易于本地化的字符串为.getString
formatArgs
原因是允许翻译者在语言需要时切换第三资源中的参数顺序。例如,如果假设语言中唯一有效的句法是In %d file(s) it found %d match(es).
,则翻译者可以照常翻译复数,然后翻译第三个资源In %2$s it found %1$s.
以说明交换的顺序。