Android复数处理“零”

如果我的strings.xml中有以下多个ressource:

   <plurals name="item_shop">
        <item quantity="zero">No item</item>
        <item quantity="one">One item</item>
        <item quantity="other">%d items</item>
   </plurals>   

我正在使用以下方法向用户显示结果:

textView.setText(getQuantityString(R.plurals.item_shop, quantity, quantity));

它适用于1及以上,但如果数量为0,那么我看到“0项”。是否只有阿拉伯语支持“零”值,因为文档似乎表明了这一点?或者我错过了什么?

5个解决方案
74 votes

Android资源国际化方法非常有限。 我使用标准java.text.MessageFormat取得了更好的成功。

基本上,您所要做的就是使用标准字符串资源,如下所示:

<resources>
    <string name="item_shop">{0,choice,0#No items|1#One item|1&lt;{0} items}</string>
</resources>

然后,从代码中您所要做的就是以下内容:

String fmt = getResources().getText(R.string.item_shop).toString();
textView.setText(MessageFormat.format(fmt, amount));

您可以在MessageFormat的javadocs中阅读有关格式字符串的更多信息

Elias Mårtenson answered 2019-06-24T18:24:19Z
39 votes

来自[http://developer.android.com/guide/topics/resources/string-resource.html#Plurals:]

请注意,选择是基于语法上的必要性。 即使数量为0,也会忽略英语为零的字符串,因为0在语法上与2不同,或者除1以外的任何其他数字(“零书”,“一本书”,“两本书”等等) 上)。 不要因为两个声音只能应用于数量2这一事实而被误导:一种语言可能要求2,12,102(等等)都被视为彼此相似但与其他不同数量。 依靠你的翻译来了解他们的语言实际上坚持的区别。

总之,'零'仅用于某些语言(同样适用于'两个''少数'等),因为其他语言没有特殊的共轭,因此“零”字段被认为是不必要的

ByteMe answered 2019-06-24T18:24:58Z
12 votes

Android正在使用CLDR复数系统,这不是它的工作原理(所以不要指望这会改变)。

该系统在这里描述:

[http://cldr.unicode.org/index/cldr-spec/plural-rules]

简而言之,理解“一个”并不意味着数字1是很重要的。相反,这些关键字是类别,属于每个类别的特定数字n由CLDR数据库中的规则定义:

[http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html]

虽然似乎没有语言对0以外的任何东西使用“零”,但有些语言将0分配给“1”。 肯定有很多情况下“两个”包含其他数字而不仅仅是2。

如果Android允许您执行您的预期操作,则无法将您的应用程序正确地翻译成具有更复杂复数规则的任意数量的语言。

miracle2k answered 2019-06-24T18:26:04Z
8 votes

这是我用来处理此问题而不切换到MessageFormat的解决方法。

首先,我将“零”字符串提取到自己的字符串资源中。

<string name="x_items_zero">No items.</string>
<plurals name="x_items">
    <!-- NOTE: This "zero" value is never accessed but is kept here to show the intended usage of the "zero" string -->
    <item quantity="zero">@string/x_items_zero</item>
    <item quantity="one">One item.</item>
    <item quantity="other">%d items.</item>
</plurals>

然后我在我自己的ResourcesUtil中有一些方便的方法

public static String getQuantityStringZero(Resources resources, int resId, int zeroResId, int quantity) {
    if (quantity == 0) {
        return resources.getString(zeroResId);
    } else {
        return resources.getQuantityString(resId, quantity, quantity);
    }
}

public static String getQuantityStringZero(Resources resources, int resId, int zeroResId, int quantity, Object... formatArgs) {
    if (quantity == 0) {
        return resources.getString(zeroResId);
    } else {
        return resources.getQuantityString(resId, quantity, formatArgs);
    }
}

现在,无论何时我想使用特定字符串作为数量零,我都会调用:

String pluralString = ResourcesUtil.getQuantityStringZero(
     getContext().getResources(),
     R.plural.x_items,
     R.string.x_items_zero,
     quantity
);

我希望有更好的东西,但这至少可以完成工作,同时保持字符串资源XML清晰。

Justin Fiedler answered 2019-06-24T18:26:56Z
0 votes

如果您正在使用数据绑定,您可以通过以下方式解决此问题:

<TextView ... 
android:text="@{collection.size() > 0 ? @plurals/plural_str(collection.size(), collection.size()) : @string/zero_str}"/>
Mark answered 2019-06-24T18:27:19Z
translate from https://stackoverflow.com:/questions/5651902/android-plurals-treatment-of-zero