在法语中,复数系统将 0 视为 "other" 而不是 "one"
In French, plural system treats 0 as "other" instead of "one"
在res/values/strings.xml
中,我有
<?xml version="1.0" encoding="utf-8"?>
<resources>
<plurals name="days_amount">
<item quantity="one">%d day EN</item>
<item quantity="other">%d days EN</item>
</plurals>
</resources>
在res/values-fr/strings.xml
中,我有
<?xml version="1.0" encoding="utf-8"?>
<resources>
<plurals name="days_amount">
<item quantity="one">%d jour FR</item>
<item quantity="other">%d jours FR</item>
</plurals>
</resources>
使用英语语言环境 res.getQuantityString(R.plurals.days_amount, 0, 0)
返回:
"0 days"
这符合英语规则(即零数量 <=> 多个数量)。
但是对于法语语言环境,它返回:
"0 jours"
根据法国规则这是不合适的(又名零数量 <=> 单数)。
它应该返回 "O jour"
法国规则:http://www.unicode.org/cldr/charts/25/supplemental/language_plural_rules.html#fr
所以,这是一个错误,还是我做错了什么?
你做错了什么。它完全按照您的指示去做。
您的规则规定当值为 other
时,使用 "days" 或 "jours"。然后您传入值 0,即 other
,因此它会根据要求使用 "days" 和 "jours"。
您可以尝试为数量 "zero" 设置第三个值,它具有特定于语言的规则。
我认为你的代码是正确的。原因如下:
- Android documentation contains the text
zero, one, two, few, many, and other
, which exactly matches the wording of the Unicode language plural rules。这表明 Android 使用了它们。
- 这些复数规则规定 0 本书 的法语案例由
one
案例处理。
由于 Android 文档没有明确提及 Unicode 语言的复数规则,您应该要求 Android 支持人员进行澄清。
在这样做之前,您应该咨询 this other question,法国的规则显然行之有效。
确实,您的担心是对的,在法语中,金额 0 应被视为“one
”而不是“other
”。问题出在某些 Android API 中:API <= 16
因此,如果您仍想支持 API 16,只需为零金额添加一个额外的字符串键。假设您有:
<plurals name="label_message_reminder_text">
<item quantity="other">Vous avez %1$s nouveaux messages</item>
<item quantity="one">Vous avez %1$s nouveau message</item>
</plurals>
只需添加一个额外的字符串:
<string name="label_message_reminder_text_zero">Vous avez %1$s nouveau message</string>
然后在检索复数时可以这样做:
String newMessagesText = getMyString(context, resourceId, amount);
messageTextView.setText(String.format(newMessagesText, amount));
你可以有一个方法来执行 getMyString():
public String getMyString(Context context, int resourceId, int amount){
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) {
if(amount == 0) {
switch (resourceId) {
case R.plurals.label_message_reminder_text:
return context.getResources().getString(R.string.label_message_reminder_text_zero);
}
}
}
return context.getResources().getQuantityString(resourceId, amount);
}
在res/values/strings.xml
中,我有
<?xml version="1.0" encoding="utf-8"?>
<resources>
<plurals name="days_amount">
<item quantity="one">%d day EN</item>
<item quantity="other">%d days EN</item>
</plurals>
</resources>
在res/values-fr/strings.xml
中,我有
<?xml version="1.0" encoding="utf-8"?>
<resources>
<plurals name="days_amount">
<item quantity="one">%d jour FR</item>
<item quantity="other">%d jours FR</item>
</plurals>
</resources>
使用英语语言环境 res.getQuantityString(R.plurals.days_amount, 0, 0)
返回:
"0 days"
这符合英语规则(即零数量 <=> 多个数量)。
但是对于法语语言环境,它返回:
"0 jours"
根据法国规则这是不合适的(又名零数量 <=> 单数)。
它应该返回 "O jour"
法国规则:http://www.unicode.org/cldr/charts/25/supplemental/language_plural_rules.html#fr
所以,这是一个错误,还是我做错了什么?
你做错了什么。它完全按照您的指示去做。
您的规则规定当值为 other
时,使用 "days" 或 "jours"。然后您传入值 0,即 other
,因此它会根据要求使用 "days" 和 "jours"。
您可以尝试为数量 "zero" 设置第三个值,它具有特定于语言的规则。
我认为你的代码是正确的。原因如下:
- Android documentation contains the text
zero, one, two, few, many, and other
, which exactly matches the wording of the Unicode language plural rules。这表明 Android 使用了它们。 - 这些复数规则规定 0 本书 的法语案例由
one
案例处理。
由于 Android 文档没有明确提及 Unicode 语言的复数规则,您应该要求 Android 支持人员进行澄清。
在这样做之前,您应该咨询 this other question,法国的规则显然行之有效。
确实,您的担心是对的,在法语中,金额 0 应被视为“one
”而不是“other
”。问题出在某些 Android API 中:API <= 16
因此,如果您仍想支持 API 16,只需为零金额添加一个额外的字符串键。假设您有:
<plurals name="label_message_reminder_text">
<item quantity="other">Vous avez %1$s nouveaux messages</item>
<item quantity="one">Vous avez %1$s nouveau message</item>
</plurals>
只需添加一个额外的字符串:
<string name="label_message_reminder_text_zero">Vous avez %1$s nouveau message</string>
然后在检索复数时可以这样做:
String newMessagesText = getMyString(context, resourceId, amount);
messageTextView.setText(String.format(newMessagesText, amount));
你可以有一个方法来执行 getMyString():
public String getMyString(Context context, int resourceId, int amount){
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) {
if(amount == 0) {
switch (resourceId) {
case R.plurals.label_message_reminder_text:
return context.getResources().getString(R.string.label_message_reminder_text_zero);
}
}
}
return context.getResources().getQuantityString(resourceId, amount);
}