fc2ブログ

戌印-INUJIRUSHI- (Androidあれこれ)

Androidのプログラミングをメインにしてます。記事に貼られたソースコードはダブルクリックすることで行番号をはずしてコピーすることができます。

 
1
2
3
4
5
6
7
8
9
11
12
13
14
15
17
18
19
20
21
22
24
25
26
27
28
29
30
06

多言語対応 : updateConfiguration

前回、『多言語対応 : res/values-○○』でリソースフォルダを分けることでOSの言語設定に合わせて表示する言語を変更する方法を書きました。

今回は、ソースコード上で表示する言語(リソースファイル)を切り替える方法について書きます。
この方法を使うことで、ゲームアプリでよく見かける言語選択画面を表示し、ユーザーに任意の言語を選択させることが可能になります。
※ リソースファイルの生成は『多言語対応 : res/values-○○』を参照してください

ソースコード上で言語を切り替えるには Configuration クラスで管理されている Locale を変更し、Resources#updateConfiguration() でアプリに反映します。

以下のサンプルソースは画面を開く度に日本語と英語を切り替えます。
package jp.inujirushi.android.sample;

import java.util.Locale;

import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;

public class TestActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// Resouces クラスから Configuration を取得する
Configuration config = getResources().getConfiguration();

// 日本語と英語を切り替える
Locale locale = config.locale;
if (Locale.JAPAN.equals(locale)) {
config.locale = Locale.ENGLISH;
} else {
config.locale = Locale.JAPAN;
}

// 変更した内容を反映する (引数が null であれば変更されない)
getResources().updateConfiguration(config, null);

// レイアウトを設定する
setContentView(R.layout.activity_layout);
}
}
この方法で変更した言語はプロセスが生きている間、有効です。
アプリを強制終了させたり、メモリ不足でメモリが解放されたりすると設定が解除されます。
そのため、実際に使う場合には変更した言語をプリファレンス等に保存し、アプリ起動時に設定するようにします。

また、変更した Locale は現在表示されているレイアウトには適用されません
変更後はレイアウトを再生成する必要があります (29-30行目)

設定されている Locale は以下の方法で取得できます。
// デバイスの言語設定で設定されている Locale を取得する
Locale locale = Locale.getDefault();

// デバイスで選択可能な Locale を取得する
Locale[] locales = Locale.getAvailableLocales();

// アプリで選択されている Locale を取得する
Locale appLocale = getResources().getConfiguration().locale;

スポンサーサイト



多言語対応 : res/values-○○

Android では、言語や地域(国)に応じて表示する文字列を変えることができます。

ソフトウェア技術ドキュメントを勝手に翻訳:
7.1 リソースの提供
7.4 ローカライズ

参考サイト:
TechBooster リソースの多言語対応
ISO 639-1 コードリスト


通常、文字列は res/values フォルダにある strings.xml に定義しています。
特定の言語や地域の場合のみ表示する文字列を変える(翻訳する)場合には、values の後ろに修飾子を付けたフォルダを作成します。

android_res_locale.png

作成するファイル名、および、リソース名は同じ名称になります。

デバイスの言語設定と一致するフォルダが存在すれば、そのフォルダ内のリソースを参照します。
フォルダが存在しない、または、該当するリソース名が無い場合には res/values フォルダを参照します。

res/values/string.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">AndroidSample</string>
<string name="menu_settings">Settings</string>
</resources>

res/values-ja/string.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">アンドロイドサンプル</string>
</resources>

上記の場合、言語設定が「日本語」であれば app_name は「アンドロイドサンプル」、menu_settings は「Settings」と表示されます。

なお、一部だけ翻訳している状態で Android Lint が実行されている場合、以下のエラーが発生することがあります。
Issue: Checks for incomplete translations where not all strings are translated

Android Lint を無視しても動作しますが、無視した場合、漏れが発生する可能性があります。
多言語対応を行う場合には一部の文字列だけでなく、全ての文字列を翻訳するようにしましょう。

■ 形式
フォルダ名: res/values[-言語コード[-地域コード]]
言語コード: ISO 639-1
地域コード: ISO 3166-1-alpha-2

例:
res/values    標準
res/values-ja   日本語
res/values-en   英語
res/values-en-rGB 英語(イギリス)
res/values-en-rUS 英語(アメリカ合衆国)

備考:
言語コードは『ISO 639-1 コードリスト』様のお世話になっています。
そちらに書かれているように、ヘブライ語、インドネシア語、イディッシュ語のコードは置き換えられています。

原文:Android Developers - java.util.Locale
Note that Java uses several deprecated two-letter codes. The Hebrew ("he") language code is rewritten as "iw", Indonesian ("id") as "in", and Yiddish ("yi") as "ji". This rewriting happens even if you construct your own Locale object, not just for instances returned by the various lookup methods.

地域コードを指定する場合には、言語コードも合わせて指定する必要があります。地域コード単独での指定はできません
また、地域コードは言語と区別するため接頭辞に「r」をつける必要があります。


アプリ内(ソースコード上)での変更は次回…

EditText のヒントを改行させない

Android で文字入力を行うための EditText 。
hint 属性を指定することで入力が空のときに何を入力すればいいのかの説明を EditText 内に表示することができます。

ただしこの hint 属性の表示行は、入力文字との行とはやや異なります。
EditText の lines 属性や singleLine 属性を指定することで1行になるように指定した場合、入力文字は1行になるがヒントは複数行表示されてしまいます。

android_edittext_hint1.png


この問題は ellipsize 属性を合わせて指定することで解消することができます。
android:ellipsize="end"
android:singleLine="true"
android_edittext_hint2.png

【参考サイト】
stackoverflow - Android: EditText hint in single line
(日本語のサイトは見つけれなかった…)


■ XMLで定義する場合
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:ellipsize="end"
android:hint="EditText のヒントは android:ellipsize を合わせて指定することで1行になる"
android:singleLine="true" />
</LinearLayout>


■ ソースコードで定義する場合
package jp.inujirushi.android.sample;

import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils.TruncateAt;
import android.widget.EditText;
import android.widget.LinearLayout;

public class TestActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// EditTextを生成する
EditText editText = new EditText(this);
editText.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT));

// ヒントを1行表示にする
editText.setSingleLine(true);
editText.setEllipsize(TruncateAt.END);
editText.setHint("EditText のヒントは android:ellipsize を合わせて指定することで1行になる");

// レイアウトを生成する
LinearLayout layout = new LinearLayout(this);
layout.addView(editText);

// レイアウトを設定する
setContentView(layout);
}
}


そもそも改行するような長いヒント書くな、という話ですよね…。
プロフィール

とむ・やむくん

Author:とむ・やむくん
管理人について

Windows 7 / 64bit
Eclipse 4.2 Juno (日本語パッチ済)

スポンサーサイト
最新トラックバック
検索フォーム
ブロとも申請フォーム
QRコード
QR
Twitter
2013/01/04 19:00 カウント開始