冷静に考えれば、そりゃそうなるわな、という話なんですが、ハマったので整理しつつメモ。
結論
- 複数形リソース(Quantity Strings (Plurals))を使う場合は、必ず
other
は定義すること。- 端末が日本語設定の場合は常に
other
しか使用されない。 -
other
以外を使う言語の場合でも、数詞に対応する文字列リソースがなければother
を使うようfallbackしてくれる。 -
other
すら無ければ、Resources.NotFoundExceptionで落ちる。
- 端末が日本語設定の場合は常に
- Lintでも怒ってくれない様子。
例
複数形に対応しようとして、 res/values/string.xml
に以下のように書いている。
<plurals name="plural_book">
<item quantity="one">Buy one book</item>
<item quantity="other">Buy %1$d books</item>
</plurals>
非日本語ユーザーに対して、とりあえず英語で表示されるように、デフォルトの文字列リソースは英語にしてある。
日本語リソースはまだ作っていない状態。
この時、本体の言語設定を「日本語」にして実際に実行してみると、指定する数量に関係なく常にother
の方が使われる。
getResources().getQuantityString(R.plurals.plural_book, 1); // → Buy %1$d books
getResources().getQuantityString(R.plurals.plural_book, 4, 4); // → Buy 4 books
なぜかというと日本語設定だから。
日本語には複数形がないので、常にother
が使われる。
端末の言語設定を英語にして動かしてみると、ちゃんと切り替わる。
実際にアプリを作っている最中に、とりあえずone
だけ定義してコードの方も数量が常に1になる状態で動かしたら、other
が無くて落ちてしまった事があった。
仕様
APIリファレンス
APIリファレンスにも、第2引数に渡された数に応じて、現在の言語に応じて適切なものを選択すると書いてある。
quantity The number used to get the correct string for the current language's plural rules.
[https://developer.android.com/reference/android/content/res/Resources.html#getQuantityString(int, int)](https://developer.android.com/reference/android/content/res/Resources.html#getQuantityString(int, int))
Common Locale Data Repository
どの数詞を使うかは、UnicodeのCommon Locale Data Repositoryのルールに基づいて選択される。
この表では、Japaneseは常にother
が使われる事になっている事が解る。
http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html
実際のリソースの選択には、International Components for UnicodeのPluralRulesクラスが使用されている(Resourcesクラスの実装参照)。
Resources#getQuantityText
ドキュメントに明記されている箇所を見つけることは出来なかったが、実装上はzero
やone
などに対応するリソースを見つけられない場合はother
を使用するようになっている。
other
すら見つけられない場合はResources.NotFoundExceptionになる。
実用例
拙作の絵文字入力アプリでは、入力しようとしている文字数に応じてメッセージを切り替えるために複数形リソースを使用している。
先の例と同様に、デフォルトの言語リソースは英語で作成している。
one
の数詞が無い言語(中国語とか)では、文字数に関係なく常に「Use Emojis」と複数形で表示されてしまうが、キリがないので気にしていない。
<plurals name="message_use_emojis">
<item quantity="one">Use Emoji</item>
<item quantity="other">Use Emojis</item>
</plurals>
日本語用のリソースではother
だけ定義してある。
<plurals name="message_use_emojis">
<item quantity="other">絵文字を使う</item>
</plurals>
参考
- Resources | Android Developers
https://developer.android.com/reference/android/content/res/Resources.html - String Resources | Android Developers
https://developer.android.com/guide/topics/resources/string-resource.html - Common Locale Data Repository - Wikipedia
http://ja.wikipedia.org/wiki/Common_Locale_Data_Repository