Android如何在运行时更改应用程序语言

23

我希望用户可以使用下拉框或其他方式更改应用程序的语言。 我尝试了很多种方法,但它们只会更改当前活动的语言,而不是所有活动的语言,并且我想要保存所选语言,在用户重新启动应用程序时仍然保留。

4个回答

38

你可以在spinner或任何你想要的方式中使用这段代码。

String languageToLoad  = "en"; // your language 
Locale locale = new Locale(languageToLoad);  
Locale.setDefault(locale); 
Configuration config = new Configuration(); 
config.locale = locale; 
getBaseContext().getResources().updateConfiguration(config,  
getBaseContext().getResources().getDisplayMetrics());

那么你应该像这样保存语言

SharedPreferences languagepref = getSharedPreferences("language",MODE_PRIVATE);
SharedPreferences.Editor editor = languagepref.edit();
editor.putString("languageToLoad",languageToLoad );
editor.commit();  

并且在每个活动中使用相同的代码在onCreate()方法中从SharedPreferences加载languageToLoad


这个更改会影响整个安卓系统还是仅限于应用程序?我问这个问题是为了当用户离开应用程序后,他们可以继续使用安卓默认语言。 - Karue Benson Karue
@KarueBensonKarue 这只会在应用程序中更改。 - Shahzain ali

7
这是一个老问题,但我仍然会回答它 :-) 你可以扩展Application类,将Abol3z的解决方案应用于每个Activity。创建类:
public class MyApplication extends Application {

   @Override
   public void onCreate() {
       super.onCreate();
       SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
       String lang = preferences.getString("lang", "en");
       Locale locale = new Locale(lang);
       Locale.setDefault(locale);
       Configuration config = new Configuration();
       config.locale = locale;
       getBaseContext().getResources().updateConfiguration(config,
               getBaseContext().getResources().getDisplayMetrics());    
   }  
}

在清单文件中将MyApplication设置为应用程序类:
 <application
        android:name=".MyApplication"
        ...
 />

你可以在你的下拉列表中设置语言值(lang):
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getContext());
preferences.edit().putString("lang", "en").commit();

2
根据文档,Application onCreate()仅在应用程序启动时调用。因此,您并没有真正在运行时更改语言,而是在下一次应用程序启动时更改,对吗?编辑:重新阅读原始问题,您的方法最终解决了问题。 - Micha

5

使用SharedPreferences来跟踪用户选择的语言,并在onCreate()和可能的onResume()方法中设置活动以使用该语言。这样可以在应用程序重新启动等情况下保持语言设置。


1
所有开发者都使用这种方式在他们的应用程序中吗?我觉得这并不太清晰! - Firas Al Mannaa
1
我不能代表其他开发者发言,因为我无法访问他们的代码。 - Raghav Sood
1
是的,这是传递一个Activity中的信息到其他活动的推荐和更清晰的方式。另一种更hacky /不合适的方法是将数据作为Activity中的静态字段保留,并从其他活动访问它,但如果有人问,我没有告诉你! :) - Shivan Dragon
抱歉,但我的意思是这个官方的方式吗?因为我需要最好的方法来实现。如果您知道,请告诉我。 - Firas Al Mannaa
1
我做到了。这是一个不错的、官方的、干净的API,你可以用它来在活动和应用程序重新启动时持久化数据。 - Raghav Sood

2
btnChange.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mContext);
            //preferences.edit().putString("lang", "bn").commit();

            String lang = preferences.getString("lang", "en");
            //Log.e("lang", "lang in Main Activity:"+lang);
            if (lang.equalsIgnoreCase("en")){
                setLocale("bn");
                preferences.edit().putString("lang", "bn").commit();
                btnChange.setText("Eng");
            }else if(lang.equalsIgnoreCase("bn")){
                setLocale("en");
                preferences.edit().putString("lang", "en").commit();
                btnChange.setText("বাংলা");
            }
        }
    });


public void setLocale(String lang) {

    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, MainActivity.class);
    startActivity(refresh);
    finish();
}

我们为测试目的使用了两种语言,将所有字符串放在名为values和values-bn的不同文件夹中。


2
conf.locale = myLocale已经过时了。res.updateConfiguration(conf, dm);也已经过时。 - kuzdu
你能否使用 recreate 代替重新启动Activity? - DFJ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接