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

muk*_*esh 92 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);
}
Run Code Online (Sandbox Code Playgroud)

我在Manifest中声明了 android:configChanges ="locale"

它有效,但有一些问题.

问题:-

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

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

Udh*_*hay 159

这是网页的摘录: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); 
} 
Run Code Online (Sandbox Code Playgroud)

确保导入以下包:

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; 
Run Code Online (Sandbox Code Playgroud)

将清单添加到活动android:configChanges ="locale | orientation"

  • 嗨,我做到了,它有效,但是当我重新启动应用程序时,它会返回默认语言. (8认同)
  • `finish()`需要在`startActivity(refresh)`之前调用.否则App可能会退出而不是重新启动的Activity. (6认同)
  • 配置config = new Configuration(newConfig); config.locale = locale; 在我的情况下收到此消息.语言环境在API级别25中已弃用 (4认同)
  • 请务必添加finish(),以便在导航堆栈中没有活动的两个副本. (3认同)
  • 此答案需要更新,因为现在不推荐使用某些 API。 (3认同)
  • 当然可以.我可以提供网页的摘录.我需要提供的地方请告诉我.谢谢. (2认同)
  • 这将如何工作? (2认同)

sud*_*007 11

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

创建您自己的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));
}
Run Code Online (Sandbox Code Playgroud)


Fra*_*jak 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
}
Run Code Online (Sandbox Code Playgroud)


Lok*_*ari 5

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

 defaultConfig {

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

}
Run Code Online (Sandbox Code Playgroud)

之后,所有语言开始运行

  • 它不工作 (3认同)
  • @JCarlosR 是的。当我在配置文件中添加语言时,Udhay 的代码开始运行 (2认同)

Osc*_*nez 5

使用上下文扩展的 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
}
Run Code Online (Sandbox Code Playgroud)

用法

override fun attachBaseContext(newBase: Context?) {
    super.attachBaseContext(newBase?.applyNewLocale(Locale("es", "MX")))
}
Run Code Online (Sandbox Code Playgroud)