*別に strings.xml という名前である必要はありません。stringsForScreen1.xml など任意のファイル名が使えます。
例えば、eclipse で Android プロジェクトを作成した場合、
デフォルトで作られる strings.xml は次のようになっています。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, MainActivity!</string>
<string name="app_name">HelloWorld</string>
</resources>
この文字列にアクセスするには、例えば、
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
や
TextView textView = (TextView)findViewById(R.id.textview);
textView.setText(R.string.hello);
String hello = getString(R.string.hello);
String hello2 = (String) getText(R.string.hello);
のようにします。
ここまでが基本的な strings.xml の話です。
ここからが本題
文字列の一部をプログラムから指定できるようしてみます。
■ "本を◯◯冊買います" の場合
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="buybooks">本を%1$d冊買います</string>
</resources>
String buybooks = getString(R.string.buybooks, 4);
%1$d の 1$ は getString() の2番目以降の引数を割り当てるときに、何番目の引数かを指定する番号です。
%d は数字, %s は文字列です。このあたりは Formatter で規定されています。
■ "☓☓を◯◯冊買います" の場合
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="buyitems">%2$sを%1$d冊買います</string>
</resources>
String buybooks = getString(R.string.buybooks, 4, ”本");
String buybooks2 = String.format(getString(R.string.buybooks), 4 , "本");
1$, 2$ で順番を指定できると、多言語の文法に対応することができます。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="buyitems">Buy %1$d %2$s</string>
</resources>
String buybooks = getString(R.string.buybooks, 4, books);
String buybooks2 = String.format(getString(R.string.buybooks), 4 , books);
■ 文法の複数形に対応する - plurals -
さて、英語の場合、次の書き方では問題があります。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="buybooks">Buy %1$d books</string>
</resources>
買う本が1冊の場合、文法的には "Buy 1 book" が正しいからです。
このように、単数形と複数形の違いに対応するために plurals が用意されています。
res/values/ の下の任意の xml ファイルで plurals を定義します。
例えば、
res/values/plurals.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<plurals name="plural_book">
<item quantity="one">Buy one book</item>
<item quantity="other">Buy %1$d books</item>
</plurals>
</resources>
quantity に設定できる値は "zero" | "one" | "two" | "few" | "many" | "other" です。
item の値の形式は string と同じ
String buy1book = getResources().getQuantityString(R.plurals.buybooks, 1);
String buynbooks = getResources().getQuantityString(R.plurals.buybooks, 4, 4);
getQuantityString(int id, int qunatity) や getQuantityString(int id, int quantity, Object... fromatArgs) で取得する。
■ HTML markup でスタイリング
xml で定義する文字列には、<b>bold text</b>, <i>italic text</i>, <u>underline text<u> が使えます。
例えば、
<string name="hello">Hello World, <b>MainActivity!</b></string>
ただし、この場合 getText(int resId) での取得はエラーになります。
format + HTML markup の場合
<string name="buybooksbold">本を<b>%1$d</b>冊買います</string>
String buybooksbold = getString(R.string.buybooksbold, 4);
TextView textView = (TextView)findViewById(R.id.textview);
textView.setText(buybooksbold);
と書いても、太字になりません。
format されるときに、文字列のすべてのスタイル情報を取り除いてしまうからです。
そのため、まず、html エスケープな文字列として xml に定義し、format したあとで fromHtml(String) メソッドを使って HTML text をスタイルします。
<string name="buybooksbold">本を<b>%1$d</b>冊買います</string>
String buybooksbold = getString(R.string.buybooksbold, 4);
CharSequence styledText = Html.fromHtml(buybooksbold);
TextView textView = (TextView)findViewById(R.id.textview);
textView.setText(styledText);
Document には、
”fromHtml(String) はすべての HTML entity に対して適応されてしまいますので、format で挿入する文字列も htmlEncode(String) でエスケープする必要があります。”
と書いてあるんだけど、エスケープしなくてもいけたのでよくわからない。
ちなみにエスケープするなら、こんな感じになります。
<string name="buyitemsbold"><b>%2$s</b>を<b>%1$d</b>冊買います</string>
String buyitemsbold = getString(R.string.buyitemsbold, 4, TextUtils.htmlEncode("本"));
CharSequence styledText = Html.fromHtml(buyitemsbold);
TextView textView = (TextView)findViewById(R.id.textview);
textView.setText(styledText);
■ 注意 : xml で定義する文字列に ' が含まれている場合、エスケープが必要
これはOK
<string name="good_example">"This'll work"</string>
<string name="good_example_2">This\'ll also work</string>
これはダメ
<string name="bad_example">This doesn't work</string>
<string name="bad_example_2">XML encodings don't work</string>
■ String Resources
■ public final String getString(int resId)
■ public final CharSequence getText(int resId)
0 件のコメント:
コメントを投稿