Previously on my last blog.
<string name="remaining_time_message">Only %d minutes left.</string>
String.format(getResources().getString(R.string.remaining_time_message, 10);
In most cases this code works well except in case of singular.
When minute value is singular, the message 'only 1 minutes left.' will be created.
It's wrong message to be accurate. We hope the message 'only 1 minute left.'
For the solution of this problem, we can write like this way.
<string name="remaining_time_message_one">Only 1 minute left.</string>
<string name="remaining_time_message_other">Only %d minutes left.</string>
if (value == 1) {
String.format(getResources().getString(R.string.remaining_time_message_one);
} else {
String.format(getResources().getString(R.string.remaining_time_message_other, value);
}
This code may work well. But there is something wrong with this solution because for example in our language Japanese, there is no differences between in the singular and in the plural.
Japanese doesn't perceive singular as special.
Therefore more properly you need to write this way.
if (Locale.getDefault() == Locale.US || Locale.getDefault() == ...) {
if (value == 1) {
String.format(getResources().getString(R.string.remaining_time_message_one);
} else {
String.format(getResources().getString(R.string.remaining_time_message_other, value);
}
} else {
String.format(getResources().getString(R.string.remaining_time_message_other, value);
}
At last the code works correctly!
But the code above is against total multilingualization because java code is aware of various of languages.
It seems to be difficult to solve it, but with xliff we can write very easy code.
[values] - strings.xml
<plurals name="remaining_time_message">
<item quantity="one">Only 1 minute left.</item>
<item quantity="other">Only <xliff:g id="minutes">%d</xliff:g> minutes left.</item>
</plurals<
[values-ja] - strings.xml
<plurals name="remaining_time_message">
<item quantity="other">残り <xliff:g id="minutes">%d</xliff:g>分</item>
</plurals>
String quantityString = getResources().getQuantityString(R.plurals.remaining_time_message, 10);
String.format(quantityString, minuteValue);
Do you know the merit of this way?
In this way, you don't have to be aware of any languages in Java code.
If you make your program accommodate different languages forward, you don't have to edit Java code at all but just pass translator the xml file and ask for translation. That's all. It's very useful, isn't it?
[In Japanese]
前回のブログの続きです。
<string name="remaining_time_message">Only %d minutes left.</string>
String.format(getResources().getString(R.string.remaining_time_message, 10);
上記のコードはほとんどの場合で正常に動作します。例外は単数形の場合です。
分の数値が1の場合、'only 1 minutes left.'というメッセージが生成される事になります。
これは厳密には間違いで、正しくは'only 1 minute left.'です。
この問題の対処として、次のようなコードを書いたとします。
<string name="remaining_time_message_one">Only 1 minute left.</string>
<string name="remaining_time_message_other">Only %d minutes left.</string>
if (value == 1) {
String.format(getResources().getString(R.string.remaining_time_message_one);
} else {
String.format(getResources().getString(R.string.remaining_time_message_other, value);
}
これも正常に動くように見えます。が、少しだけ問題があります。我々の言語である日本語の場合だと、
単数形の場合と複数形の場合で違うフォーマットのメッセージになるという事はあまりありません。
日本語では単数形を特別扱いしないのです。
なので、より正確には次のようなコードを書く必要があります。
if (Locale.getDefault() == Locale.US || Locale.getDefault() == ...) {
if (value == 1) {
String.format(getResources().getString(R.string.remaining_time_message_one);
} else {
String.format(getResources().getString(R.string.remaining_time_message_other, value);
}
} else {
String.format(getResources().getString(R.string.remaining_time_message_other, value);
}
これで正しく動くプログラムが完成しました。
しかし、残念ながらこれは完全な多言語化対応のプログラムとは言えません。なぜなら、Javaのソースの中で言語を意識してしまっているからです。
この種の問題に完全に対処するのは難しいと感じるかもしれませんが、XLIFFを使用すると簡単に解決できます。
[values] - strings.xml
<plurals name="remaining_time_message">
<item quantity="one">Only 1 minute left.</item>
<item quantity="other">Only <xliff:g id="minutes">%d</xliff:g> minutes left.</item>
</plurals<
[values-ja] - strings.xml
<plurals name="remaining_time_message">
<item quantity="other">残り <xliff:g id="minutes">%d</xliff:g>分</item>
</plurals>
String quantityString = getResources().getQuantityString(R.plurals.remaining_time_message, 10);
String.format(quantityString, minuteValue);
今までとの違いが分かるでしょうか?
このやり方だと、Javaのソース上で言語を意識している箇所を排除できます。
つまり、今後色んな言語に対応させる事になった場合でもJavaのソースは修正しなくてよく、翻訳家の方にxmlファイルを渡して翻訳を依頼すればいいだけになります。
すごい恩恵だと思いませんか?