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


106

アプリでスペイン語、ポルトガル語、英語の3つの言語をサポートする必要があります。アプリで言語を選択するオプションを提供します。

1)3つの描画可能なフォルダーdrawable-es、drawable-pt、drawable。

2)言語に従って3つの値のフォルダーvalues-es、values-pt、values.Change 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)方向変更後、アプリは電話のロケールに応じて言語を復元します。


1
2番目の問題については、次を追加してみandroid:configChanges="locale"てください。AndroidManifest.xml内のアクティビティ
Parth Doshi

マニフェストのすべてのアクティビティをすでに追加しています。
mukesh '16年

言語リスト、設定画面の設定を提供し、アプリケーションの言語をオーバーライドする次のライブラリを使用できます:github.com/delight-im/Android-Languages
caw

回答:


172

ウェブページの抜粋です: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); 
    finish();
    startActivity(refresh); 
} 

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

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"に追加します


2
そうだね。ウェブページの抜粋を提供できます。提供する必要がある場所を教えてください。ありがとう。
Udhay、2012年

3
ナビゲーションスタックにアクティビティのコピーが2つないように、必ずfinish()を追加してください。
Joel Teply、2015年

6
finish()前に呼び出す必要がありますstartActivity(refresh)。そうしないと、アクティビティが再起動されずにアプリが終了する場合があります。
Mohammed Ali

10
こんにちは..私はそれをしなかった、それは動作しますが、私はアプリを再起動すると、それがデフォルトの言語に戻ります
ソフィアンHassaini

5
構成config = new Configuration(newConfig); config.locale =ロケール; 私の場合、このメッセージが表示されます。APIレベル25で廃止されたロケール
Milon

9

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

独自のCustomContextWrapperクラス拡張ContextWrapperを作成し、それを使用して完全なアプリケーションのロケール設定を変更します。 以下は使用法のGISTです。

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

@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(MyContextWrapper.wrap(newBase, language));
}

リンクのおかげで、それが働いているが、私はいくつかのことを理解していなかった、私はちょうどと呼ばれるMyContextWrapper.warponAttach私のアプリのただ一つの断片のが、言語は全体のアプリのために変更されましたが、活動のタイトルが変更されていなかった、私はそれを考えますこれは、マニフェストのタイトルが優先されるためですがonAttachBaseContex、アプリケーションのサブクラスで同じメソッドを呼び出すと、アクティビティのタイトルも選択した言語に変更されますが、変更は、warpメソッドで呼び出したフラグメントにのみ適用されます。 ?
Abhinav Chauhan

@AbhinavChauhanこれが本当かどうかはわかりません。確認する必要があります。このソリューションを実装したときに、この問題に直面したことはありません。ただし、長い間使用されており、新しいバージョンのAndroid実装にいくつかの変更がある可能性があります。または、この投稿で最新の回答をいくつか試してください。
sud007

私は多くの解決策を試しましたが、それらのいずれかが機能しないか、間違って実装した可能性があります、あなたのクラスはアクティビティでうまく機能しますか?私はフラグメントのwarpメソッドを使用しonAttachていますアプリ全体は本当ですが、他のすべてのフラグメントの場合、構成の変更時に言語が英語に変更されるためonattach、すべてのフラグメントを挿入する必要があり、マニフェストの代わりにコードにアクションバーのタイトルを設定すると、アプリは期待どおりに機能します。ありがとう
Abhinav Chauhan

はい!すべての画面でこれを実行する必要はなく、attachBaseContext関数内でのみ起動する最初のアクティビティのみです。そして、それはすべての画面でそれを行います。アプリのすべてのアクティビティに対して「BaseActivity」を作成しましたか?
sud007

いいえ、アプリケーション全体に適用され、次にすべてのフラグメントに適用されると考えて、アプリケーションのサブクラスでそれを実行しようとしましたが、wrap()コードはすべての構成変更で実行する必要があることが判明したので、他のすべてのアクティビティの延長となる抽象的なアクティビティ、現在は機能しています
Abhinav Chauhan

6

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
}

android:configChanges = "locale"をマニフェストから削除しても、アプリの再起動は妨げられません。マニフェストに追加されているかどうかに関係なく再起動します。
ポートフォリオ

マニフェストからandroid:configChanges = "locale"を削除すると、アプリが再起動できなくなると言っているのではなく、まったく逆です。さて、マニフェストにandroid:configChanges = "locale"が含まれている場合、これは、私がこの回答を書いたときにアプリが再読み込みされないようにするために使用されていました。
Frane Poljak、2018

6

上記のすべての@Udayのコードは完璧ですが、1つだけ不足しています(build.gradleのデフォルト構成)

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); 
finish();
startActivity(refresh); 

}

構成ファイル(build.gradle)に言語が記載されていないだけで鉱山が機能しなかった

 defaultConfig {
    resConfigs "en", "hi", "kn"
}

その後、すべての言語が実行され始めました


3
機能しない
Krunal Shah

本当に必要ですか?
JCarlosR

1
@JCarlosRはい。構成ファイルに言語を追加すると、Udhayのコードが実行を開始しました
Lokesh Tiwari

3

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

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

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();
    } 

メニュー文字列と同じ問題。あなたは問題を解決しますか?
AlexS

@AlexS、メニュー文字列の問題を修正する方法が見つかりませんでした。しかし、アプリを終了してから再入力することがわかった場合、メニュー文字列は通常、新しいロケールに変更できます。
フィッシャー

どういう意味Intent refresh = new Intent(this, ThisActivity.class); startActivity(refresh);
AlexS

2
@AlexS、いいえ!新しいIntent()とstartActivity()を追加すると、アプリを再起動したときにデフォルトの言語に戻る場合があります。つまり、ユーザーがアプリを終了して再度アプリに入ると、メニュー文字列を新しいロケールに変更できます。
フィッシャー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.