web-dev-qa-db-ja.com

ユーザーが言語を選択したときにアプリの言語を変更するにはどうすればよいですか?

アプリでスペイン語、ポルトガル語、英語の3つの言語をサポートしたい。そして、アプリで言語を選択するオプションを与えます。

1)drawable-es、drawable-pt、drawableの3つのdrawableフォルダー。

2)3つの値フォルダーvalues-es、values-pt、values。言語に従ってString.xmlの値を変更します。

言語を選択するimageViewがあります。クリックすると、オプションの英語、スペイン語、ポルトガル語で構成されるメニューが開きます。

このコードによるオプション選択でアプリ内のロケールを設定します

public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.en:
             Locale locale = new Locale("en"); 
             Locale.setDefault(locale);
             Configuration config = new Configuration();
             config.locale = locale;
             getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
             Toast.makeText(this, "Locale in English !", Toast.LENGTH_LONG).show();
             break;

        case R.id.pt:
             Locale locale2 = new Locale("pt"); 
             Locale.setDefault(locale2);
             Configuration config2 = new Configuration();
             config2.locale = locale2;
             getBaseContext().getResources().updateConfiguration(config2, getBaseContext().getResources().getDisplayMetrics());

             Toast.makeText(this, "Locale in Portugal !", Toast.LENGTH_LONG).show();
             break;

        case R.id.es:
             Locale locale3 = new Locale("es"); 
             Locale.setDefault(locale3);
             Configuration config3 = new Configuration();
             config3.locale = locale3;
             getBaseContext().getResources().updateConfiguration(config3, getBaseContext().getResources().getDisplayMetrics());

             Toast.makeText(this, "Locale in Spain !", Toast.LENGTH_LONG).show();
             break;     
    }
    return super.onOptionsItemSelected(item);
}

マニフェストで宣言しました-Android:configChanges = "locale"

動作しますが、いくつかの問題があります。

問題:-

1)言語を選択すると、言語選択の画像で構成される画面は変わりませんが、他の画面は変わります。

2)向きを変更した後、アプリは電話のロケールに従って言語を復元します。

89
mukesh

ウェブページの抜粋: http://Android.programmerguru.com/Android-localization-at-runtime/

ユーザーが言語のリストからアプリを選択すると、アプリの言語を変更するのは簡単です。以下のようなメソッドを使用して、ロケールを文字列として受け入れ(英語の場合は 'en'、ヒンディー語の場合は 'hi'など)、アプリのロケールを構成し、言語の変更を反映するように現在のアクティビティを更新します。適用したロケールは、手動で再度変更するまで変更されません。

public void setLocale(String lang) { 
    Locale myLocale = new Locale(lang); 
    Resources res = getResources(); 
    DisplayMetrics dm = res.getDisplayMetrics(); 
    Configuration conf = res.getConfiguration(); 
    conf.locale = myLocale; 
    res.updateConfiguration(conf, dm); 
    Intent refresh = new Intent(this, AndroidLocalize.class); 
    startActivity(refresh); 
    finish();
} 

次のパッケージをインポートしたことを確認してください。

import Java.util.Locale; 
import Android.os.Bundle; 
import Android.app.Activity; 
import Android.content.Intent; 
import Android.content.res.Configuration; 
import Android.content.res.Resources; 
import Android.util.DisplayMetrics; 

マニフェストをアクティビティに追加Android:configChanges = "locale | orientation"

154
Udhay

マニフェストからAndroid:configChanges="locale"を削除すると、アクティビティがリロードされるか、onConfigurationChangedメソッドがオーバーライドされます。

@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
    // your code here, you can use newConfig.locale if you need to check the language
    // or just re-set all the labels to desired string resource
}
6
Frane Poljak

良い解決策はここでかなりよく説明されています。しかし、もう一つあります。

CustomContextWrapperを拡張する独自のContextWrapperクラスを作成し、それを使用して完全なアプリケーションのロケール設定を変更します。 ここに要点があります 使用法。

そして、保存されたロケール識別子でCustomContextWrapperを呼び出します。アクティビティライフサイクルメソッドattachBaseContextのヒンディー語の'hi'。ここでの使用法:

@Override
protected void attachBaseContext(Context newBase) {
    // fetch from shared preference also save the same when applying. Default here is en = English
    String language = MyPreferenceUtil.getInstance().getString("saved_locale", "en");
    super.attachBaseContext(SnapContextWrapper.wrap(newBase, language));
}
4
sud007

上記のすべてのコードは完璧ですが、これが欠けているのは、言語が設定ファイルで言及されていないという理由だけで機能していませんでした

 defaultConfig {

    resConfigs "en", "hi", "kn"

}

その後、すべての言語が実行を開始しました

4
Lokesh Tiwari

Udhayのサンプルコードはうまく機能します。 Sofiane HassainiとChirag SolankIの質問を除いて、再入に関しては、うまくいきません。 super.onCreate(savedInstanceState);の前にonCreate()でアクティビティを再起動せずにUdhayのコードを呼び出そうとします。それでは大丈夫です!少し問題がありますが、メニュー文字列はまだ設定されたロケールに変更されていません。

    public void setLocale(String lang) { //call this in onCreate()
      Locale myLocale = new Locale(lang); 
      Resources res = getResources(); 
      DisplayMetrics dm = res.getDisplayMetrics(); 
      Configuration conf = res.getConfiguration(); 
      conf.locale = myLocale; 
      res.updateConfiguration(conf, dm); 
      //Intent refresh = new Intent(this, AndroidLocalize.class); 
      //startActivity(refresh); 
      //finish();
    } 
2
Fisher

バージョンの問題が発生した場合は、このコードを試してください..

public static void switchLocal(Context context, String lcode, Activity activity) {
        if (lcode.equalsIgnoreCase(""))
            return;
        Resources resources = context.getResources();
        Locale locale = new Locale(lcode);
        Locale.setDefault(locale);
        Android.content.res.Configuration config = new 
        Android.content.res.Configuration();
        config.locale = locale;
        resources.updateConfiguration(config, resources.getDisplayMetrics());
        //restart base activity 
        activity.finish();
        activity.startActivity(activity.getIntent());
    }
2