Android のローカライズ
このドキュメントでは、Android SDK のローカライズ機能と、Xamarin でそれらにアクセスする方法について説明します。
Android プラットフォーム機能
このセクションでは、Android の主なローカライズ機能について説明します。 特定のコードと例を確認するには、次のセクションに進んでください。
ロケール
ユーザーは、[設定] > 「言語と入力] で言語を選択します。 この選択により、表示される言語と使用されるリージョン設定の両方を制御します (日付と数値の書式設定など)。
現在のロケールは、現在のコンテキストの Resources
を使用して照会できます。
var lang = Resources.Configuration.Locale; // eg. "es_ES"
この値は、アンダースコアで区切られた言語コードとロケール コードの両方が含まれるロケール識別子になります。 参考までに、Java ロケールのリストと StackOverflow を使用して Android でサポートされるロケールを示します。
たとえば、次のような場合です。
en_US
: 英語 (米国)es_ES
: スペイン語 (スペイン)ja_JP
: 日本語 (日本)zh_CN
: 中国語 (中国)zh_TW
: 中国語 (台湾)pt_PT
: ポルトガル語 (ポルトガル)pt_BR
: ポルトガル語 (ブラジル)
LOCALE_CHANGED
Android では、ユーザーが言語の選択を変更すると、android.intent.action.LOCALE_CHANGED
が生成されます。
アクティビティがこれを処理することを選択できるようにするには、次のようにアクティビティに android:configChanges
属性を設定します。
[Activity (Label = "@string/app_name", MainLauncher = true, Icon="@drawable/launcher",
ConfigurationChanges = ConfigChanges.Locale | ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
Android での国際化の基本
Android のローカライズ戦略には、次の重要な部分があります。
ローカライズされた文字列、イメージ、その他のリソースを含むリソース フォルダー。
コード内のローカライズされた文字列を取得するために使用される
GetText
メソッドローカライズされた文字列をレイアウトに自動的に配置する AXML ファイル内の
@string/id
リソース フォルダー
Android アプリケーションは、次のようなリソース フォルダー内のほとんどのコンテンツを管理します。
- layout - AXML レイアウト ファイルが含まれます。
- drawable - イメージとその他のドローアブル リソースが含まれます。
- values - 文字列が含まれます。
- raw - データ ファイルが含まれます。
ほとんどの開発者は、drawable ディレクトリの dpi サフィックスを使用して複数のバージョンのイメージを提供し、Android が各デバイスの正しいバージョンを選択できるようにすることに既に慣れ親しんでいます。 同じメカニズムを使用して、リソース ディレクトリに言語識別子とカルチャ識別子のサフィックスを付けることで、複数の言語翻訳を提供します。
Note
es
のような最上位言語を指定する場合、2 文字のみが必要です。ただし、完全なロケールを指定する場合、ディレクトリ名の形式では、2 つの部分を区切るためにダッシュと小文字の r が必要です (例: pt-rBR または zh-rCN)。 これを、アンダースコアを持つ、コードで返される値と比較してください (例: pt_BR
)。 これらは両方とも、.NET の CultureInfo
クラスが使用する、ダッシュのみが含まれる値 (例: pt-BR
) とは異なります。 Xamarin プラットフォーム間で作業する場合は、これらの違いに留意してください。
Strings.xml ファイル形式
ローカライズされた values ディレクトリ (例: values-es または values-pt-rBR) には、そのロケールに関して翻訳されたテキストを含む Strings.xml という名前のファイルが含まれる必要があります。
翻訳可能な各文字列は、リソース ID が name
属性として指定され、翻訳された文字列が値として指定された XML 要素です。
<string name="app_name">TaskyL10n</string>
通常の XML 規則に従ってエスケープする必要があり、name
は有効な Android リソース ID (スペースまたはダッシュなし) である必要があります。 この例の既定の (英語) 文字列ファイルを次に示します。
values/Strings.xml
<resources>
<string name="app_name">TaskyL10n</string>
<string name="taskadd">Add Task</string>
<string name="taskname">Name</string>
<string name="tasknotes">Notes</string>
<string name="taskdone">Done</string>
<string name="taskcancel">Cancel</string>
</resources>
スペイン語のディレクトリ values-es には、翻訳が含まれる同じ名前 (Strings.xml) を持つファイルが含まれています。
values-es/Strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">TaskyLeon</string>
<string name="taskadd">agregar tarea</string>
<string name="taskname">Nombre</string>
<string name="tasknotes">Notas</string>
<string name="taskdone">Completo</string>
<string name="taskcancel">Cancelar</string>
</resources>
文字列ファイルが設定されたら、翻訳された値をレイアウトとコードの両方で参照できます。
AXML レイアウト ファイル
レイアウト ファイル内のローカライズされた文字列を参照するには、@string/id
構文を使用します。 このサンプルの XML スニペットは、ローカライズされたリソース ID を使用して設定された text
プロパティを示しています (その他のいくつかの属性は省略されています)。
<TextView
android:id="@+id/NameLabel"
android:text="@string/taskname"
... />
<CheckBox
android:id="@+id/chkDone"
android:text="@string/taskdone"
... />
GetText メソッド
コード内の翻訳された文字列を取得するには、GetText
メソッドを使用し、リソース ID を渡します。
var cancelText = Resources.GetText (Resource.String.taskcancel);
Quantity 文字列
Android 文字列リソースを使用すると、quantity 文字列を作成できます。これにより、翻訳者がさまざまな数量に対してさまざまな翻訳を提供できるようになります。次に例を示します。
- "タスクが 1 個残っています。"
- "実行すべきタスクがまだ 2 個あります。"
(一般的な "タスクが n 個残っています" ではありません)。
Strings.xml 内
<plurals name="numberOfTasks">
<!--
As a developer, you should always supply "one" and "other"
strings. Your translators will know which strings are actually
needed for their language.
-->
<item quantity="one">There is %d task left.</item>
<item quantity="other">There are %d tasks still to do.</item>
</plurals>
完全な文字列をレンダリングするには、GetQuantityString
メソッドを使用して、表示するリソース ID と値を渡します (2 回渡します)。 2 番目のパラメーターは、使用する文字列 quantity
決定するために Android によって使用されます。3 番目のパラメーターは、実際に文字列に置き換える値です (両方が必要です)。
var translated = Resources.GetQuantityString (
Resource.Plurals.numberOfTasks, taskcount, taskcount);`
有効な quantity
スイッチは次のとおりです。
- ゼロ
- 1
- 2 つ
- few
- many
- other
これらについては、Android ドキュメントで詳しく説明します。特定の言語で "特殊な" 処理が必要ない場合、これらの quantity
文字列は無視されます (たとえば、英語では one
と other
のみを使用します。zero
文字列を指定しても効果はなく、この文字列は使用されません)。
Images
ローカライズされたイメージは、文字列ファイルと同じ規則に従います。アプリケーションで参照されるすべてのイメージを drawable ディレクトリに配置し、フォールバックが行われるようにする必要があります。
その後、ロケール固有のイメージを drawable-es や drawable-ja などの修飾された drawable フォルダーに配置する必要があります (dpi 指定子も追加できます)。
このスクリーンショットでは、4 つのイメージが drawable ディレクトリに保存されていますが、唯一、flag.png のみに、その他のディレクトリにローカライズされたコピーがあります。
その他のリソースの種類
レイアウト、アニメーション、生ファイルなど、その他の種類の代替言語固有のリソースを提供することもできます。 つまり、1 つ以上のターゲット言語に特定の画面レイアウトを提供できます。たとえば、非常に長いテキスト ラベルを使用できるドイツ語専用のレイアウトを作成できます。
Android 4.2 では、アプリケーション設定 android:supportsRtl="true"
を設定した場合における右から左に読む (RTL) 言語のサポートが導入されました。 リソース修飾子 "ldrtl"
をディレクトリ名に含めることで、RTL 表示用に設計されたカスタム レイアウトを含めることができます。
リソース ディレクトリの名前付けとフォールバックの詳細については、代替リソースの提供に関する Android ドキュメントを参照してください。
アプリ名
アプリケーション名は、MainLauncher
アクティビティに @string/id
を使用することで、簡単にローカライズできます。
[Activity (Label = "@string/app_name", MainLauncher = true, Icon="@drawable/launcher",
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Locale)]
右から左に読む (RTL) 言語
Android 4.2 以降では、ネイティブ RTL サポート ブログで詳しく説明されている、RTL レイアウトが完全にサポートされています。
Android 4.2 (API レベル 17) 以降を使用する場合、配置値は、left
と right
の代わりに start
と end
を使用して指定できます (例: android:paddingStart
)。 また、RTL の読者に適応する画面の構築に役立つ、LayoutDirection
、TextDirection
、TextAlignment
のような新しい API もあります。
次のスクリーンショットは、アラビア語でローカライズされた Tasky サンプルを示しています。
次のスクリーンショットは、ヘブライ語でローカライズされた Tasky サンプルを示しています。
RTL テキストは、LTR テキストと同じ方法で Strings.xml ファイルを使用してローカライズされます。
テスト
必ず既定のロケールを十分にテストしてください。 何らかの理由で既定のリソースを読み込むことができない (つまり、これらが不足している) 場合、アプリケーションはクラッシュします。
エミュレーターのテスト
ADB シェルを使用してエミュレーターを特定のロケールに設定する方法については、Google の「Android Emulator でのテスト」セクションを参照してください。
adb shell setprop persist.sys.locale fr-CA;stop;sleep 5;start
デバイス テスト
デバイスでテストするには、設定アプリで言語を変更します。
ヒント
言語を元の設定に戻すことができるように、メニュー項目のアイコンと場所をメモしておいてください。
まとめ
この記事では、組み込みのリソース処理を使用した Android アプリケーションのローカライズの基本について説明しています。 iOS、Android、クロスプラットフォーム アプリ (Xamarin.Forms を含む) の i18n と L10n の詳細については、このクロスプラットフォーム ガイドを参照してください。