简介
Android 从 Android 1.0 就支持复数(数量字符串)。它是基于 XML 的资源,在 XML 文件中指定数量zero
、one
、two
、few
、many
和 other
的值,并在代码中使用 getQuantityString()
方法获取语法正确的值。
选择使用哪一个字符串完全取决于语法上的必要性,如在中文中根本不做这些语法区分,因此获取的始终是 other
字符串,在英语中数量为 0,表示 zero
的字符串也会被忽略,因为在语法上,0 与 2 或除 1 以外的任何其他数字并无区别(“zero books” “one book” “two books”等)。
语法
XML 文件位置:res/values/filename.xml
文件名可以任意设置。<plurals>
元素的 name 用作资源的 ID。quantity
表示应在何时使用该字符串的值。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<plurals
name="plural_name">
<item
quantity=["zero" | "one" | "two" | "few" | "many" | "other"]
>text_string</item>
</plurals>
</resources>
以下是关键字 quantity
的可用值的说明:
值 | 说明 |
zero | 当某种语言要求对数字 0(如阿拉伯语中的 0)进行特殊处理时。 |
one | 当某种语言要求对 1 这类数字(如英语和大多数其他语言中的数字 1;在俄语中,任何末尾为 1 但非 11 的数字均属此类)进行特殊处理时。 |
two | 当某种语言要求对 2 这类数字(如威尔士语中的 2,或斯洛文尼亚语中的 102)进行特殊处理时。 |
few | 当某种语言要求对“小”数字(如捷克语中的 2、3 和 4;或波兰语中末尾为 2、3 或 4,但非 12、13 或 14 的数字)进行特殊处理时。 |
many | 当某种语言要求对“大”数字(如马耳他语中末尾为 11 至 99 的数字)进行特殊处理时。 |
other | 当某种语言未要求对给定数量(如中文中的所有数字,或英语中的 42)进行特殊处理时。 |
示例:
res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<plurals name="numberOfSongsAvailable">
<item quantity="one">%d song found.</item>
<item quantity="other">%d songs found.</item>
</plurals>
</resources>
用法:
String songsFound = getResources().getQuantityString(R.plurals.numberOfSongsAvailable, count, count);
// 第一个 count 参数会选择合适的复数字符串,第二个 count 参数会插入 %d 占位符内。如果您的复数字符串没有字符串格式设置,则无需向 getQuantityString 传递第三个参数。
在 API 24 及更高级别的版本上,可以改为使用功能更强大的 ICU [MessageFormat](https://developer.android.com/reference/android/icu/text/MessageFormat)
类。
在 JetpackCompose 中使用复数资源
从 Compose 1.2 开始,我们可使用 pluralStringResource
API 加载复数字符串。源码中该方法调用的是 getQuantityString
方法。
pluralStringResource(R.plurals.runtime_format, quantity, quantity)
目前的 Compose 版本(1.2.1)中它仍然是一个实验性的 API,所以需要添加注解:@ExperimentalComposeUiApi
这个方法在 Compose 1.2 之前的版本中不可用,可以继续使用 Android SDK 的 getQuantityString
方法。
LocalContext.current.resources.getQuantityString(R.plurals.runtime_format, quantity, quantity)
Compose 中是是怎样实现的
如下是源码中在 Compose 中添加对复数资源的支持的代码:
https://android-review.googlesource.com/c/platform/frameworks/support/+/1999932/3/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/res/StringResources.android.kt#80
/**
* Load a plurals resource.
*
* @param id the resource identifier
* @param count the count
* @return the pluralized string data associated with the resource
*/
@Composable
@ReadOnlyComposable
fun pluralStringResource(@PluralsRes id: Int, count: Int): String {
val resources = resources()
return resources.getQuantityString(id, count)
}
/**
* Load a plurals resource with provided format arguments.
*
* @param id the resource identifier
* @param count the count
* @param formatArgs arguments used in the format string
* @return the pluralized string data associated with the resource
*/
@Composable
@ReadOnlyComposable
fun pluralStringResource(@PluralsRes id: Int, count: Int, vararg formatArgs: Any): String {
val resources = resources()
return resources.getQuantityString(id, count, *formatArgs)
}