美文网首页Android开发
用plurals写复数形式字符串

用plurals写复数形式字符串

作者: 灰灰手记 | 来源:发表于2016-05-11 17:35 被阅读1097次

在开发中,我们有时候需要对特定文字加上复数形式,而不同语言下,复数形式是不一样的,比如:

中文:
1 本书;
2 本书;
3 本书;
......

我们发现这里变化的只是前面的数字,后面的文字是完全一样的,也就是说这里的单复数形式是一样的,没必要做区分,因此一个string资源就可以搞定:

    <string name="numberOfBooks">%d 本书</string>

但如果是英文呢?

英文:
1 book;
2 books;
3 books;
...

这个时候我们发现变化的不只是前面的数字了,后面的book也发生了变化,也就是说这里的单复数已经是两种形式了,因此要换成字符串资源,就需要两个string了:

    <string name="oneBooks">%d book</string>
    <string name="manyBooks">%d books</string>

为了很好的适配这两个string,我们在代码中还要加上相应的判断。这样一来就显得繁琐了,那么有没有一种字符串资源能够自动帮助我们实现单复数切换呢?
幸运的是,Android里面就提供了这么一种String资源:plurals。接着使用上面的例子,这时英文下只需要这么写:

    <plurals name="numberOfBooks" >
        <item quantity="one">%d book</item>
        <item quantity="other">%d books</item>
    </plurals>

写法类似于string-array,但在使用上却和普通的是string资源有着相似之处,例如:

    String one = getResources().getQuantityString(R.plurals.numberOfBooks, 1, 1);
    String two = getResources().getQuantityString(R.plurals.numberOfBooks, 2, 2);

这里通过上面的方法我们就能取到相应的单复数形式的字符串资源了。
这里的getQuantityString方法有2种重载形式:

getQuantityString的2种重载形式

我们可以看到,这2种重载形式中都有2个共同的参数:

int id,是我们在string.xml里面写的plurals资源的id;
int quantity,是数量的意思,也就是我们取具体item的判断依据。

此外的Object... formatArgs参数应该就不需要解释了。


上面写我们plurals资源的时候,quantity属性我们只用了其中两个值,实际上它有好几种取值,如下表:

Value Description
zero 当前语言需要特别对待0
one 当前语言需要特别对待1
two 当前语言需要特别对待2
few 当前语言需要特别对待few/small,也就是小数量的
many 当前语言需要特别对待many/large,也就是大数量的
other 当前语言没有要求对特定资源进行特殊对待

细心的读者会发现,上面我们反复提到了“当前语言”,为什么呢?
想知道为什么,看源码就知道了。
我们跟进getQuantityString的实现源码:

    public String getQuantityString(@PluralsRes int id, int quantity, Object... formatArgs)
            throws NotFoundException {
        String raw = getQuantityText(id, quantity).toString();
        return String.format(mConfiguration.locale, raw, formatArgs);
    }

我们发现这个方法调用了String.format方法进行字符串格式化,如下:

    String.format(mConfiguration.locale, raw, formatArgs);

我们知道String.format有2种重载形式,其中一种第一个参数是:Locale locale,这个参数就是机器当前的语言环境,嗯,先记住这个点。
接下来我们继续跟进mConfiguration.locale的实现源码:

    /**
     * Current user preference for the locale, corresponding to
     * <a href="{@docRoot}guide/topics/resources/providing-resources.html#LocaleQualifier">locale</a>
     * resource qualifier.
     */
    public Locale locale;

很明显,这里的mConfiguration.locale就是一个Locale对象,so,后面不用我解释了......


可能有的人尝试写满了zero, one, two, few, many, other,但运行起来,机器并没有按他以为的那样显示相应的item,然后就认为是我在瞎忽悠。这一点,我们一直在强调的“当前语言”就可以解释了,简单的说就是程序运行的时候,具体取的那个item,是取决于当前语言对单复数等形式的定义的,并不是你写的你认为的那样的定义。

相关文章

  • 用plurals写复数形式字符串

    在开发中,我们有时候需要对特定文字加上复数形式,而不同语言下,复数形式是不一样的,比如: 中文:1 本书;2 本书...

  • 关于plurals用法经验

    plurals是value.xml中的一个标签属性,用于解决不同个数下使用不同字串的问题。最为经典的是单复数形式下...

  • Python入门基础知识点

    命名规则 变量名可以使用大写字母开头,但是不建议。 类名开头大写 列表用单词复数形式 修改字符串的大小写 Yuqi...

  • 今天是整理笔记的一天

    可数名词的数 复数形式规则变化 复数形式不规则变化 合成名词的复数变化 集体名词的数 总以复数...

  • 接口规范

    1. URI规范 不用大写 用 "-" 不用 "_" 参数列表要encode 资源集合,用复数形式表示 在REST...

  • both, either, neither的用法

    01Both both表示“(两者)都”,可以代指可数名词复数,做主语时,谓语动词用主语是复数时的形式,比如:I ...

  • 可数名词的复数变化规则

    名词复数 Plural Nouns 可数名词有单数和复数两种形式,表示两个或两个以上的概念时,要用复数形式。名词复...

  • Python 学习之路: Session 状态

    Cookie: Cookie,有时也用其复数形式 Cookies,指某些网站为了辨别用户身份、进行 session...

  • a/an 的省略

    a/an 不用在以下几种情况下: 复数名词之前: a/an没有复数形式,所以a dog的复数是dogs,an eg...

  • 项目二:复数抽象数据类型

    项目内容 理解复数ADT的形式描述 运用C语言对复数ADT进行表示 运用C语言实现复数ADT中定义的操作 调用复数...

网友评论

  • 脏仙人:能问下当前语言具体是什么意思么?例如我在Android的dome中写满了zero, one, two, few, many, other的Item但是只有输入1的时候才显示one的Item,2就显示了other。是什么情况
    灰灰手记:@浮世绘黑猫 你把机器语言切成英文,或者其他有类似one book, two books 这种变化的语言,然后在App里面适配相应的语言,再运行看看:blush:
    脏仙人:@js_灰灰 我的机器好像是中文呀。=、=
    灰灰手记: @浮世绘黑猫 就是当前系统使用的语言。2显示other说明你的机器当前用的语言里面,没有对2进行特殊对待,你的机器是不是中文的?😎

本文标题:用plurals写复数形式字符串

本文链接:https://www.haomeiwen.com/subject/uejurttx.html