如何使用Android数量字符串(复数) [英] How to use Android quantity strings (plurals)

查看:42
本文介绍了如何使用Android数量字符串(复数)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 getQuantityString 方法根据 Android 开发人员指南检索数量字符串(复数)数量字符串(复数)

I am trying to use the getQuantityString method in Resources to retrieve quantity strings (plurals) based on Android Developer guidelines Quantity string (plurals)

我得到的错误是

错误:(604) 以非位置格式指定的多个替换;您的意思是添加 formatted="false" 吗?属性?
错误:(604)在预期位置找到标签

Error:(604) Multiple substitutions specified in non-positional format; did you mean to add the formatted="false" attribute?
Error:(604) Found tag where is expected

当我如下设置复数时

<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>

并尝试阅读如下productIndexCountText.setText(getResources().getQuantityString(R.plurals.productCount, position, size));

And trying to read it as below productIndexCountText.setText(getResources().getQuantityString(R.plurals.productCount, position, size));

一种解决方法是将字符串拆分为仅对字符串的最后一部分使用复数,然后将两部分连接起来.但我尽量避免这样做.

One workaround is to break the string up to use plural only for the last part of the string and concatenate the two parts. But I am trying to avoid doing that if possible.

推荐答案

你不需要设置格式化"任何这些项目的属性.使用数量字符串时,只有三种可能:

You don't need to set the "formatted" attribute for any of those items. When using quantity strings, there are only three possibilities:

  1. 资源字符串为纯文本,不包含任何参数
  2. 资源字符串只包含一个参数(很可能是数量);使用 %d 或您需要的任何格式
  3. 资源字符串包含多个参数;所有参数都必须通过它们的位置显式访问,例如 %1$d
  1. the resource string is plain text and does not contain any parameters
  2. the resource string contains only one parameter (most likely the quantity); use %d or whatever format you need
  3. the resource string contains multiple parameters; all parameters have to be explicitly accessed by their position, for example %1$d

至于 getQuantityString 方法,有两种重载:一种只有资源 ID 和数量,另一种带有附加的 Object... formatArgs 参数.

As for the getQuantityString method, there are two overloads: one with only the resource id and the quantity, and one with an additional Object... formatArgs parameter.

对于情况 1.,您可以使用 getQuantityString(@PluralsRes int id, intquantity) 方法.

For case 1., you can use the getQuantityString(@PluralsRes int id, int quantity) method.

对于所有其他情况,我.e.如果您有任何参数,则需要getQuantityString(@PluralsRes int id, intquantity, Object... formatArgs) 重载.注意:所有 参数必须出现在参数数组中.这意味着,如果资源字符串显示数量,则数量变量将两次传递给函数.

For all other cases, i. e. if you have any parameters, you need the getQuantityString(@PluralsRes int id, int quantity, Object... formatArgs) overload. Note: all parameters have to be present in the parameter array. That means, if the resource string displays the quantity, the quantity variable will be passed twice to the function.

那是因为解析资源字符串的位置参数时没有考虑方法本身的quantity参数.

That is because the quantity parameter of the method itself is not considered when resolving the positional parameters of your resource string.

如果这些是您的资源,

<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 的适当调用是:

then the appropriate calls to getQuantityString are:

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参数

如上所述,关键是要明白getQuantityStringquantity参数不是用来代替%d%1$d.相反,它用于从 plurals 本身结合资源文件的区域设置确定适当的 item.


Quantity classes: understanding the quantity parameter

As stated above, the key is to understand that the quantity parameter of getQuantityString is not used to replace the placeholders like %d or %1$d. Instead, it is used to determine the appropriate item from the plurals itself, in combination with the locale of the resource file.

但是请注意,与属性名称及其可能值(zeroonetwo>fewmanyother) 可能会建议.例如,提供额外的 将不起作用(至少不是英文),即使quantity参数的值为0.

Beware however that this is a less direct mapping than the attribute's name and its possible values (zero, one, two, few, many, other) might suggest. For example, providing an additional <item quantity="zero"> will not work (at least not in English), even if the value of the quantity parameter is 0.

原因是复数在Android中的工作方式是通过数量类的概念.数量类是在给定语言中具有相同语法规则的一组数量值.这关键意味着

The reason is that the way plurals work in Android is by the concept of quantity classes. A quantity class is a set of quantity values that have the same grammatical rules in a given language. This crucially means that

  • 使用了哪些数量类别,以及
  • 哪些数值被映射到它们

取决于相应资源文件的区域设置.

is dependent on the locale the respective resource file is for.

重要的是要了解这两个问题仅由语法必要性决定.以下是一些示例:

It is important to understand that both questions are decided only by grammatical necessity. Here are some examples:

  • 在中文或韩文中,仅使用other,因为在这些语言中,句子在语法上不会根据给定的数量而有所不同.
  • 在英语中,有两个类: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 甚至不一定只代表一个数字.
  • In Chinese or Korean, only other is used, because in these languages sentences don't grammatically differ based on the given quantity.
  • In English, there's two classes: one for the literal value 1, and other for all other values including 0.
  • In Irish, 1 is mapped to one, 2 is mapped to two, 3-6 is few, 7-10 is many, 0 and 11+ is other.
  • In Slovenian, the value 1 and all values ending in 01 are mapped to one (1, 101, 3001, ...). 2 and values ending in 02 are mapped to two (2, 302, 1002, ...). 3, 4 and values ending in 03 or 04 are mapped to few (3, 4, 6004, ...). Anything else is other (0, 11, 48, 312, ...).
  • In Polish, 5-19 and values ending in 05-19 are mapped to many (5, 12, 216, 4711, ...). Values ending in 2, 3 or 4 including 2-4 themselves are mapped to few (3, 42, 103, 12035374, ...). This respects however that 12, 13 and 14 are exceptions from this rule because they are mapped to many. (Side note: yes, grammatically speaking, 5 is many while 12035374 is few.)
  • Armenian is like English, with the exception that the value 0 is also mapped to one, because that's how their grammar works. You can see from this example that the quantity class one doesn't even necessarily represent just one-ish numbers.

如您所见,确定正确的数量类别会变得相当复杂.这就是为什么 getQuantityString 已经根据 quantity 参数和资源文件的语言环境为您做这件事的原因.Android(主要)所遵循的规则在语言中定义Unicode 通用语言环境数据存储库 的复数规则.这也是数量类名称的由来.

As you can see, it can get fairly complicated to determine the correct quantity class. That's why getQuantityString already does that for you, based on the quantity parameter and the resource file's locale. The rules Android (mostly) plays by are defined in the Language Plural Rules of the Unicode Common Locale Data Repository. That is also where the names of the quantity classes come from.

所有这一切意味着翻译任何数量字符串所需的数量类集可以因语言而异(中文只需要other,英文需要oneother,爱尔兰需要除 zero 以外的所有内容,等等).但是,在一种语言中,所有 复数 都应该具有相同数量的项目,涵盖该特定语言所需的所有数量类别.

All that means that the set of quantity classes needed to translate any quantity string can differ from language to language (Chinese just needs other, English needs one and other, Irish needs all but zero, etc.). Within one language however, all plurals should each have the same number of items covering all quantity classes necessary for that particular language.

getQuantityString 的调用可以这样理解:

A call to getQuantityString can be understood like this:

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 波兰语.

The quantity parameter's value of "5" will mean the used item will be the one with the quantity class other from Chinese, Korean, English, Slovenian and Armenian resource files, few for Irish, and many for Polish.

我还要简要提及两种特殊情况:

There are two special cases I'd also briefly mention:

基本上,选择的类再次取决于特定于语言的规则.选择类的方式既不通用,也不保证涵盖所有整数规则所需的任何类也可用于任何非整数.以下是一些示例:

Basically, the chosen class depends on language-specific rules again. It is neither universal how a class is chosen, nor guaranteed that any class required to cover all rules for integers is also used for any non-integers. Here are a few examples:

  • 对于英语,任何带小数的值将始终映射到other.
  • 对于斯洛文尼亚语,任何带小数的值将始终映射到 few.
  • 对于爱尔兰语,选择取决于整数部分.
  • 对于波兰语,与整数的复杂规则相反,非整数总是映射到 other 就像英语一样.
  • For English, any value with decimals will always map to other.
  • For Slovenian, any value with decimals will always map to few.
  • For Irish, the choice depends on the integer part.
  • For Polish, in contrast to the complex rules for integers, non-integers are always mapped to other like in English.

注意:根据语言复数规则.唉,Android 目前还没有现成的 floatdouble 方法.

Note: This is how it should be according to the Language Plural Rules. Alas, Android has no readily available method for float or double at the moment.

如果您的显示文本有多个数量,例如.G.在 %d 个文件中找到 %d 个匹配项.,将其拆分为三个单独的资源:

If your display text has multiple quantities, e. g. %d match(es) found in %d file(s)., split it into three separate resources:

  1. %d 个匹配项(复数项)
  2. %d 个文件(复数项)
  3. %1$s 在 %2$s 中找到.(普通参数化strings 项)
  1. %d match(es) (plurals item)
  2. %d file(s) (plurals item)
  3. %1$s found in %2$s. (ordinary parameterized strings item)

然后,您可以对 1 和 2 对 getQuantityString 进行适当的调用,然后对第三个对 getString 进行另一个调用,前两个容易本地化的字符串为 <代码>formatArgs.

You can then make the appropriate calls to getQuantityString for 1 and 2, and then another one to getString for the third, with the first two readily localized strings as formatArgs.

原因是允许翻译人员在第三个资源中切换参数顺序,如果语言需要的话.例如,如果假设语言中唯一有效的语法是 In %d file(s) it found %d match(es).,翻译者可以照常翻译复数,然后翻译第三个资源为 在 %2$s 中,它找到了 %1$s. 来解释交换的订单.

The reason is to allow translators to switch the parameter order in the third resource, should the language require it. E.g., if the only valid syntax in a hypothetical language was In %d file(s) it found %d match(es)., the translator could translate the plurals as usual, and then translate the third resource as In %2$s it found %1$s. to account for the swapped order.

这篇关于如何使用Android数量字符串(复数)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆