当用户选择语言时如何更改应用程序的语言?

时间:2012-10-16 05:46:38

标签: android localization

我希望我的应用支持三种语言西班牙语,葡萄牙语和英语。并提供在app中选择语言的选项。我已经做了

1)3个可绘制的文件夹drawable-es,drawable-pt,drawable。

2)3个值文件夹值-es,values-pt,values。根据语言更改String.xml值。

我有imageView来选择语言。点击它打开的菜单包括选项英语,西班牙语,葡萄牙语。

我通过此代码

在选项选择中在应用内设置了Locale
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);
}

我已在Manifest声明 - android:configChanges =“locale”

它有效,但有一些问题。

问题: -

1)选择语言时,包含语言选择图像的画面不会改变,但其他画面也会改变。

2)定向更改应用程序后,根据手机的区域设置恢复语言。

9 个答案:

答案 0 :(得分:153)

摘录于网页: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”

答案 1 :(得分: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
}

答案 2 :(得分:4)

好的解决方案在这里解释得很好。但是还有一个。

创建自己的CustomContextWrapper类扩展ContextWrapper并使用它来更改整个应用程序的区域设置。 Here is a 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(SnapContextWrapper.wrap(newBase, language));
}

答案 3 :(得分:4)

以上所有代码都是完美的,但是只有一个缺少 我的行不通只是因为配置文件中未提及该语言

 defaultConfig {

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

}

之后,所有语言开始运行

答案 4 :(得分:2)

Udhay的示例代码效果很好。除了Sofiane Hassaini和Chirag SolankI的问题,重新入场,它不起作用。我尝试在super.onCreate(savedInstanceState);之前调用Udhay的代码而不重新启动onCreate()中的活动。那就没事了!   只有一点问题,菜单字符串仍然没有更改为设置的Locale。

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

答案 5 :(得分:1)

那些遇到版本问题的人尝试此代码..

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

答案 6 :(得分:1)

使用上下文扩展的Kotlin解决方案

fun Context.applyNewLocale(locale: Locale): Context {
    val config = this.resources.configuration
    val sysLocale = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        config.locales.get(0)
    } else {
        //Legacy
        config.locale
    }
    if (sysLocale.language != locale.language) {
        Locale.setDefault(locale)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            config.setLocale(locale)
        } else {
            //Legacy
            config.locale = locale
        }
        resources.updateConfiguration(config, resources.displayMetrics)
    }
    return this
}

用法

override fun attachBaseContext(newBase: Context?) {
    super.attachBaseContext(newBase?.applyNewLocale(Locale("es", "MX")))
}

答案 7 :(得分:0)

我尝试了所有解决方案,最后我明白了!
here是一个简单的项目,向您展示如何操作
快乐的编码:)

答案 8 :(得分:0)

    Locale locale = new Locale(langCode);
    Locale.setDefault(locale);
    Configuration configuration = context.getResources().getConfiguration();
    configuration.locale = locale;
    configuration.setLayoutDirection(locale); // for RTL changes
    preferences.setLocalePref(langCode);
    context.getResources().updateConfiguration(configuration, context.getResources().getDisplayMetrics());

此处,langCode 是所需的语言代码。您可以在 sharedPreferences 中将语言代码保存为字符串。您可以在 super.onCreate(savedInstanceState) 中调用此代码 onCreate