是否可以在仍使用Android资源的情况下以编程方式更改应用程序的语言?
如果不是,是否可以请求特定语言的资源?
我想让用户从应用程序中更改应用程序的语言。
是否可以在仍使用Android资源的情况下以编程方式更改应用程序的语言?
如果不是,是否可以请求特定语言的资源?
我想让用户从应用程序中更改应用程序的语言。
Answers:
这是可能的。您可以设置语言环境。但是,我不建议这样做。我们已经在早期阶段进行了尝试,基本上是在与系统抗争。
我们对更改语言有相同的要求,但决定解决UI与电话UI相同的事实。它可以通过设置区域设置来工作,但是却存在很多问题。根据我的经验,每次输入活动(每个活动)时,都必须进行设置。如果您仍然需要此代码,则提供以下代码(同样,我不建议这样做)
Resources res = context.getResources();
// Change locale settings in the app.
DisplayMetrics dm = res.getDisplayMetrics();
android.content.res.Configuration conf = res.getConfiguration();
conf.setLocale(new Locale(language_code.toLowerCase())); // API 17+ only.
// Use conf.locale = new Locale(...) if targeting lower versions
res.updateConfiguration(conf, dm);
如果您有特定于语言的内容-您可以根据设置更改该内容。
2020年3月26日更新
public static void setLocale(Activitycontext) {
Locale locale;
Sessions session = new Sessions(context);
//Log.e("Lan",session.getLanguage());
locale = new Locale(langCode);
Configuration config = new Configuration(context.getResources().getConfiguration());
Locale.setDefault(locale);
config.setLocale(locale);
context.getBaseContext().getResources().updateConfiguration(config,
context.getBaseContext().getResources().getDisplayMetrics());
}
Context.createConfigurationContext()
,可用于包装具有特定于语言环境的配置的默认上下文,然后调用该上下文getResources
,而不必更新资源对象本身的配置。
conf.setLayoutDirection(locale)
,可以替换conf.locale = new Locale(...))
使用conf.setLocale(new Locale(...))
。它将在内部调用setLayoutDirection
。
这段代码确实有效:
fa =波斯语,en =英文
在languageToLoad
变量中输入您的语言代码:
import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
public class Main extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String languageToLoad = "fa"; // your language
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
this.setContentView(R.layout.main);
}
}
Resources.updateConfiguration
。我已缩进代码以使其更加清晰。
我一直在寻找以编程方式更改系统语言的方法。尽管我完全理解,普通应用程序绝对不应这样做,而是:
有必要以编程方式真正地更改系统的语言。
这是未记录的API,因此不应用于市场/最终用户应用程序!
无论如何,这就是我找到的解决方案:
Locale locale = new Locale(targetLocaleAsString);
Class amnClass = Class.forName("android.app.ActivityManagerNative");
Object amn = null;
Configuration config = null;
// amn = ActivityManagerNative.getDefault();
Method methodGetDefault = amnClass.getMethod("getDefault");
methodGetDefault.setAccessible(true);
amn = methodGetDefault.invoke(amnClass);
// config = amn.getConfiguration();
Method methodGetConfiguration = amnClass.getMethod("getConfiguration");
methodGetConfiguration.setAccessible(true);
config = (Configuration) methodGetConfiguration.invoke(amn);
// config.userSetLocale = true;
Class configClass = config.getClass();
Field f = configClass.getField("userSetLocale");
f.setBoolean(config, true);
// set the locale to the new value
config.locale = locale;
// amn.updateConfiguration(config);
Method methodUpdateConfiguration = amnClass.getMethod("updateConfiguration", Configuration.class);
methodUpdateConfiguration.setAccessible(true);
methodUpdateConfiguration.invoke(amn, config);
android.permission.CHANGE_CONFIGURATION
只能由使用Perform键签名的应用授予。
如果要保留所有应用程序更改的语言,则必须做两件事。
首先,创建一个基本活动,并从此扩展所有活动:
public class BaseActivity extends AppCompatActivity {
private Locale mCurrentLocale;
@Override
protected void onStart() {
super.onStart();
mCurrentLocale = getResources().getConfiguration().locale;
}
@Override
protected void onRestart() {
super.onRestart();
Locale locale = getLocale(this);
if (!locale.equals(mCurrentLocale)) {
mCurrentLocale = locale;
recreate();
}
}
public static Locale getLocale(Context context){
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
String lang = sharedPreferences.getString("language", "en");
switch (lang) {
case "English":
lang = "en";
break;
case "Spanish":
lang = "es";
break;
}
return new Locale(lang);
}
}
请注意,我将新语言保存在sharedPreference中。
其次,创建如下的Application扩展:
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
setLocale();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setLocale();
}
private void setLocale() {
final Resources resources = getResources();
final Configuration configuration = resources.getConfiguration();
final Locale locale = getLocale(this);
if (!configuration.locale.equals(locale)) {
configuration.setLocale(locale);
resources.updateConfiguration(configuration, null);
}
}
}
请注意,getLocale()与上面的相同。
就这样!我希望这可以帮助某人。
Application
以及如何使用。 mobomo.com/2011/05/如何使用Android的应用程序对象
configuration.locate
已弃用,setLocale需要API 17+,并且不赞成updateConfiguration
根据 这篇文章。您将需要下载LocaleHelper.java
该文章中引用的内容。
MyApplication
将扩展的类Application
attachBaseContext()
以更新语言。在清单中注册此类。
public class MyApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.onAttach(base, "en"));
}
}
<application
android:name="com.package.MyApplication"
.../>
创建BaseActivity
并覆盖onAttach()
以更新语言。Android 6+需要
public class BaseActivity extends Activity {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.onAttach(base));
}
}
使您应用上的所有活动都从扩展BaseActivity
。
public class LocaleHelper {
private static final String SELECTED_LANGUAGE = "Locale.Helper.Selected.Language";
public static Context onAttach(Context context) {
String lang = getPersistedData(context, Locale.getDefault().getLanguage());
return setLocale(context, lang);
}
public static Context onAttach(Context context, String defaultLanguage) {
String lang = getPersistedData(context, defaultLanguage);
return setLocale(context, lang);
}
public static String getLanguage(Context context) {
return getPersistedData(context, Locale.getDefault().getLanguage());
}
public static Context setLocale(Context context, String language) {
persist(context, language);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return updateResources(context, language);
}
return updateResourcesLegacy(context, language);
}
private static String getPersistedData(Context context, String defaultLanguage) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
return preferences.getString(SELECTED_LANGUAGE, defaultLanguage);
}
private static void persist(Context context, String language) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = preferences.edit();
editor.putString(SELECTED_LANGUAGE, language);
editor.apply();
}
@TargetApi(Build.VERSION_CODES.N)
private static Context updateResources(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Configuration configuration = context.getResources().getConfiguration();
configuration.setLocale(locale);
configuration.setLayoutDirection(locale);
return context.createConfigurationContext(configuration);
}
@SuppressWarnings("deprecation")
private static Context updateResourcesLegacy(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
configuration.locale = locale;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
configuration.setLayoutDirection(locale);
}
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
return context;
}
}
只是增加了一块让我绊倒的东西。
例如,其他答案可以使用“ de”正常工作
String lang = "de";
Locale locale = new Locale(lang);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
上面的方法不适用于例如"fr_BE"
语言环境,因此它将使用values-fr-rBE
文件夹或类似名称。
需要以下细微改动才能使用 "fr_BE"
String lang = "fr";
//create a string for country
String country = "BE";
//use constructor with country
Locale locale = new Locale(lang, country);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
activity.recreate()
android.content.res.Configuration conf = res.getConfiguration();
而不是创建新Configuration
实例怎么办?使用新鲜的有什么好处吗?
我的应用程序启动后更改了德语。
这是我的正确代码。任何人都想为我使用这个。.(如何在Android中以编程方式更改语言)
我的代码:
Configuration config ; // variable declaration in globally
// this part is given inside onCreate Method starting and before setContentView()
public void onCreate(Bundle icic)
{
super.onCreate(icic);
config = new Configuration(getResources().getConfiguration());
config.locale = Locale.GERMAN ;
getResources().updateConfiguration(config,getResources().getDisplayMetrics());
setContentView(R.layout.newdesign);
}
我知道回答晚了,但是我在这里找到了这篇文章 。这很好地解释了整个过程,并为您提供了结构良好的代码。
语言环境帮助器类:
import android.annotation.TargetApi;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.preference.PreferenceManager;
import java.util.Locale;
/**
* This class is used to change your application locale and persist this change for the next time
* that your app is going to be used.
* <p/>
* You can also change the locale of your application on the fly by using the setLocale method.
* <p/>
* Created by gunhansancar on 07/10/15.
*/
public class LocaleHelper {
private static final String SELECTED_LANGUAGE = "Locale.Helper.Selected.Language";
public static Context onAttach(Context context) {
String lang = getPersistedData(context, Locale.getDefault().getLanguage());
return setLocale(context, lang);
}
public static Context onAttach(Context context, String defaultLanguage) {
String lang = getPersistedData(context, defaultLanguage);
return setLocale(context, lang);
}
public static String getLanguage(Context context) {
return getPersistedData(context, Locale.getDefault().getLanguage());
}
public static Context setLocale(Context context, String language) {
persist(context, language);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return updateResources(context, language);
}
return updateResourcesLegacy(context, language);
}
private static String getPersistedData(Context context, String defaultLanguage) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
return preferences.getString(SELECTED_LANGUAGE, defaultLanguage);
}
private static void persist(Context context, String language) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = preferences.edit();
editor.putString(SELECTED_LANGUAGE, language);
editor.apply();
}
@TargetApi(Build.VERSION_CODES.N)
private static Context updateResources(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Configuration configuration = context.getResources().getConfiguration();
configuration.setLocale(locale);
configuration.setLayoutDirection(locale);
return context.createConfigurationContext(configuration);
}
@SuppressWarnings("deprecation")
private static Context updateResourcesLegacy(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
configuration.locale = locale;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
configuration.setLayoutDirection(locale);
}
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
return context;
}
}
您需要重写attachBaseContext并调用LocaleHelper.onAttach()来初始化应用程序中的语言环境设置。
import android.app.Application;
import android.content.Context;
import com.gunhansancar.changelanguageexample.helper.LocaleHelper;
public class MainApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.onAttach(base, "en"));
}
}
您要做的就是添加
LocaleHelper.onCreate(this, "en");
无论您要更改语言环境。
createConfigurationContext
,这对您有所帮助
创建一个类扩展Application
并创建一个静态方法。然后,您可以在之前的所有活动中调用此方法setContentView()
。
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
}
public static void setLocaleFa (Context context){
Locale locale = new Locale("fa");
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
context.getApplicationContext().getResources().updateConfiguration(config, null);
}
public static void setLocaleEn (Context context){
Locale locale = new Locale("en_US");
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
context.getApplicationContext().getResources().updateConfiguration(config, null);
}
}
活动中的用法:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyApp.setLocaleFa(MainActivity.this);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
}
旧答案
这包括RTL / LTR支持:
public static void changeLocale(Context context, Locale locale) {
Configuration conf = context.getResources().getConfiguration();
conf.locale = locale;
Locale.setDefault(locale);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
conf.setLayoutDirection(conf.locale);
}
context.getResources().updateConfiguration(conf, context.getResources().getDisplayMetrics());
}
唯一对我完全有效的解决方案是Alex Volovoy的代码与应用程序重新启动机制的组合:
void restartApplication() {
Intent i = new Intent(MainTabActivity.context, MagicAppRestart.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainTabActivity.context.startActivity(i);
}
/** This activity shows nothing; instead, it restarts the android process */
public class MagicAppRestart extends Activity {
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
finish();
}
protected void onResume() {
super.onResume();
startActivityForResult(new Intent(this, MainTabActivity.class), 0);
}
}
activity.recreate()
我面临着同样的问题。在GitHub上,我找到了Android-LocalizationActivity库。
该库使在运行时更改应用程序语言变得非常简单,如下面的代码示例所示。一个示例项目,包括下面的示例代码和更多信息,可以在github页面上找到。
LocalizationActivity扩展了AppCompatActivity,因此在使用片段时也可以使用它。
public class MainActivity extends LocalizationActivity implements View.OnClickListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_simple);
findViewById(R.id.btn_th).setOnClickListener(this);
findViewById(R.id.btn_en).setOnClickListener(this);
}
@Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.btn_en) {
setLanguage("en");
} else if (id == R.id.btn_th) {
setLanguage("th");
}
}
}
进行适当更新的时间。
首先,使用已弃用的API弃用的列表:
configuration.locale
(API 17)updateConfiguration(configuration, displaymetrics)
(API 17)最近没问题的答案是正确的是新方法的使用。
createConfigurationContext是updateConfiguration的新方法。
有些人像这样单独使用它:
Configuration overrideConfiguration = ctx.getResources().getConfiguration();
Locale locale = new Locale("en_US");
overrideConfiguration.setLocale(locale);
createConfigurationContext(overrideConfiguration);
...但是那行不通。为什么?该方法返回一个上下文,然后该上下文用于处理Strings.xml转换和其他本地化资源(图像,布局等)。
正确的用法是这样的:
Configuration overrideConfiguration = ctx.getResources().getConfiguration();
Locale locale = new Locale("en_US");
overrideConfiguration.setLocale(locale);
//the configuration can be used for other stuff as well
Context context = createConfigurationContext(overrideConfiguration);
Resources resources = context.getResources();
如果只是将其复制粘贴到IDE中,则可能会看到一条警告,提示该API要求您定位到API 17或更高版本。可以通过将其放入方法并添加注释来解决此问题。@TargetApi(17)
可是等等。那旧的API呢?
您需要使用没有TargetApi批注的updateConfiguration创建另一个方法。
Resources res = YourApplication.getInstance().getResources();
// Change locale settings in the app.
DisplayMetrics dm = res.getDisplayMetrics();
android.content.res.Configuration conf = res.getConfiguration();
conf.locale = new Locale("th");
res.updateConfiguration(conf, dm);
您无需在此处返回上下文。
现在,管理这些可能很困难。在API 17+中,您需要创建上下文(或创建的上下文中的资源)以基于本地化获取适当的资源。您如何处理?
好吧,这就是我的方法:
/**
* Full locale list: /programming/7973023/what-is-the-list-of-supported-languages-locales-on-android
* @param lang language code (e.g. en_US)
* @return the context
* PLEASE READ: This method can be changed for usage outside an Activity. Simply add a COntext to the arguments
*/
public Context setLanguage(String lang/*, Context c*/){
Context c = AndroidLauncher.this;//remove if the context argument is passed. This is a utility line, can be removed totally by replacing calls to c with the activity (if argument Context isn't passed)
int API = Build.VERSION.SDK_INT;
if(API >= 17){
return setLanguage17(lang, c);
}else{
return setLanguageLegacy(lang, c);
}
}
/**
* Set language for API 17
* @param lang
* @param c
* @return
*/
@TargetApi(17)
public Context setLanguage17(String lang, Context c){
Configuration overrideConfiguration = c.getResources().getConfiguration();
Locale locale = new Locale(lang);
Locale.setDefault(locale);
overrideConfiguration.setLocale(locale);
//the configuration can be used for other stuff as well
Context context = createConfigurationContext(overrideConfiguration);//"local variable is redundant" if the below line is uncommented, it is needed
//Resources resources = context.getResources();//If you want to pass the resources instead of a Context, uncomment this line and put it somewhere useful
return context;
}
public Context setLanguageLegacy(String lang, Context c){
Resources res = c.getResources();
// Change locale settings in the app.
DisplayMetrics dm = res.getDisplayMetrics();//Utility line
android.content.res.Configuration conf = res.getConfiguration();
conf.locale = new Locale(lang);//setLocale requires API 17+ - just like createConfigurationContext
Locale.setDefault(conf.locale);
res.updateConfiguration(conf, dm);
//Using this method you don't need to modify the Context itself. Setting it at the start of the app is enough. As you
//target both API's though, you want to return the context as you have no clue what is called. Now you can use the Context
//supplied for both things
return c;
}
该代码通过使用一种方法来起作用,该方法可以根据API调用适当的方法。这是我使用许多不推荐使用的调用(包括Html.fromHtml)完成的。您有一个采用所需参数的方法,然后将其拆分为两个(或三个或三个以上)方法之一,并根据API级别返回适当的结果。由于您不必多次检查,因此它很灵活,“输入”方法可以为您完成检查。这里的进入方法是setLanguage
获取资源时,需要使用返回的Context。为什么?我在这里看到了其他答案,他们使用createConfigurationContext而不使用返回的上下文。为了使其能够正常工作,必须调用updateConfiguration。不推荐使用。使用方法返回的上下文获取资源。
用法示例:
构造函数或类似的地方:
ctx = getLanguage(lang);//lang is loaded or generated. How you get the String lang is not something this answer handles (nor will handle in the future)
然后,无论您想获得什么资源,都可以这样做:
String fromResources = ctx.getString(R.string.helloworld);
使用任何其他上下文(理论上)将打破这一点。
AFAIK您仍然必须使用活动上下文来显示对话框或Toast。为此,您可以使用活动的实例(如果您在外面)
最后,使用recreate()
该活动刷新内容。不必创建刷新意图的快捷方式。
如果你写
android:configChanges="locale"
在每个活动中(清单文件中),则无需在每次输入时进行设置Activity
。
configChanges
用hack来保留旋转/ etc上的Activity状态。
Locale locale = new Locale("en");
Locale.setDefault(locale);
Configuration config = context.getResources().getConfiguration();
config.setLocale(locale);
context.createConfigurationContext(config);
重要更新:
context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
请注意,在SDK> = 21上,您需要调用'Resources.updateConfiguration()',否则资源将不会更新。
Context ctx = createConfigurationContext(args);
并从中获取资源
/*change language at Run-time*/
//use method like that:
//setLocale("en");
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, AndroidLocalize.class);
startActivity(refresh);
}
activity.recreate()
Locale
configuration
activity
在设置内容之前,应在每个设置中设置-this.setContentView(R.layout.main);
activity.recreate()
首先,为不同的语言创建multi string.xml;然后在onCreate()
方法中使用以下代码块:
super.onCreate(savedInstanceState);
String languageToLoad = "fr"; // change your language here
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
this.setContentView(R.layout.main);
这是一些对我有用的代码:
public class MainActivity extends AppCompatActivity {
public static String storeLang;
@Override
protected void onCreate(Bundle savedInstanceState) {
SharedPreferences shp = PreferenceManager.getDefaultSharedPreferences(this);
storeLang = shp.getString(getString(R.string.key_lang), "");
// Create a new Locale object
Locale locale = new Locale(storeLang);
// Create a new configuration object
Configuration config = new Configuration();
// Set the locale of the new configuration
config.locale = locale;
// Update the configuration of the Accplication context
getResources().updateConfiguration(
config,
getResources().getDisplayMetrics()
);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
资料来源:这里
这里列出的解决方案都没有帮助我。
如果AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES),则语言无法在android> = 7.0上打开
这个LocaleUtils可以正常工作: https ://gist.github.com/GigigoGreenLabs/7d555c762ba2d3a810fe
语言工具
public class LocaleUtils {
public static final String LAN_SPANISH = "es";
public static final String LAN_PORTUGUESE = "pt";
public static final String LAN_ENGLISH = "en";
private static Locale sLocale;
public static void setLocale(Locale locale) {
sLocale = locale;
if(sLocale != null) {
Locale.setDefault(sLocale);
}
}
public static void updateConfig(ContextThemeWrapper wrapper) {
if(sLocale != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
Configuration configuration = new Configuration();
configuration.setLocale(sLocale);
wrapper.applyOverrideConfiguration(configuration);
}
}
public static void updateConfig(Application app, Configuration configuration) {
if(sLocale != null && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
//Wrapping the configuration to avoid Activity endless loop
Configuration config = new Configuration(configuration);
config.locale = sLocale;
Resources res = app.getBaseContext().getResources();
res.updateConfiguration(config, res.getDisplayMetrics());
}
}
}
将此代码添加到应用程序
public class App extends Application {
public void onCreate(){
super.onCreate();
LocaleUtils.setLocale(new Locale("iw"));
LocaleUtils.updateConfig(this, getBaseContext().getResources().getConfiguration());
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
LocaleUtils.updateConfig(this, newConfig);
}
}
活动中的代码
public class BaseActivity extends AppCompatActivity {
public BaseActivity() {
LocaleUtils.updateConfig(this);
}
}
Alex Volovoy答案仅在活动的onCreate方法中对我有用。
适用于所有方法的答案在另一个线程中
这是代码的改编
Resources standardResources = getBaseContext().getResources();
AssetManager assets = standardResources.getAssets();
DisplayMetrics metrics = standardResources.getDisplayMetrics();
Configuration config = new Configuration(standardResources.getConfiguration());
config.locale = new Locale(languageToLoad);
Resources defaultResources = new Resources(assets, metrics, config);
希望对您有所帮助。
请注意,这种使用的解决方案updateConfiguration
将在几周后不再适用于Android M版本。现在,新方法是使用参见API文档中的applyOverrideConfiguration
方法ContextThemeWrapper
自从我自己遇到问题以来,您可以在这里找到我的完整解决方案:https : //stackoverflow.com/a/31787201/2776572
您应该执行一些步骤
首先,您需要更改配置的语言环境
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
configuration.locale = new Locale(language);
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
其次,如果您希望将更改直接应用于可见的布局,则可以直接更新视图,也可以只调用activity.recreate()重新启动当前活动。
而且您还必须坚持所做的更改,因为在用户关闭应用程序之后,您将丢失语言更改。
我在我的博客文章Android中以编程方式更改语言中介绍了更详细的解决方案
基本上,您只需在应用程序类上调用LocaleHelper.onCreate()即可,如果您想即时更改语言环境,则可以调用LocaleHelper.setLocale()
当我按下按钮更改TextView的文本语言时,此方法有效。(values-de文件夹中的strings.xml)
String languageToLoad = "de"; // your language
Configuration config = getBaseContext().getResources().getConfiguration();
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
recreate();
添加LocaleHelper类
public class LocaleHelper{
private static final String SELECTED_LANGUAGE = "Locale.Helper.Selected.Language";
public static Context onAttach(Context context) {
String lang = getPersistedData(context, Locale.getDefault().getLanguage());
return setLocale(context, lang);
}
public static Context onAttach(Context context, String defaultLanguage) {
String lang = getPersistedData(context, defaultLanguage);
return setLocale(context, lang);
}
public static String getLanguage(Context context) {
return getPersistedData(context, Locale.getDefault().getLanguage());
}
public static Context setLocale(Context context, String language) {
persist(context, language);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return updateResources(context, language);
}
return updateResourcesLegacy(context, language);
}
private static String getPersistedData(Context context, String defaultLanguage) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
return preferences.getString(SELECTED_LANGUAGE, defaultLanguage);
}
private static void persist(Context context, String language) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = preferences.edit();
editor.putString(SELECTED_LANGUAGE, language);
editor.apply();
}
@TargetApi(Build.VERSION_CODES.N)
private static Context updateResources(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Configuration configuration = context.getResources().getConfiguration();
configuration.setLocale(locale);
configuration.setLayoutDirection(locale);
return context.createConfigurationContext(configuration);
}
@SuppressWarnings("deprecation")
private static Context updateResourcesLegacy(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
configuration.locale = locale;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
configuration.setLayoutDirection(locale);
}
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
return context;
}
}
活动中或片段中
Context context = LocaleHelper.setLocale(this, App.getSharedPre().getLanguage());
Resource resources = context.getResources();
现在在每个文本上设置SetText
TextView tv = findViewById(R.id.tv);
tv.setText(resources.getString(R.string.tv));
类似于已接受的答案,但为2017版本,并添加了重新启动(不重新启动,有时下一个Activity仍呈现英语):
// Inside some activity...
private void changeDisplayLanguage(String langCode) {
// Step 1. Change the locale in the app's configuration
Resources res = getResources();
android.content.res.Configuration conf = res.getConfiguration();
conf.setLocale(currentLocale);
createConfigurationContext(conf);
// Step 2. IMPORTANT! you must restart the app to make sure it works 100%
restart();
}
private void restart() {
PackageManager packageManager = getPackageManager();
Intent intent = packageManager.getLaunchIntentForPackage(getPackageName());
ComponentName componentName = intent.getComponent();
Intent mainIntent = IntentCompat.makeRestartActivityTask(componentName);
mainIntent.putExtra("app_restarting", true);
PrefUtils.putBoolean("app_restarting", true);
startActivity(mainIntent);
System.exit(0);
}
activity.recreate()
3)返回的上下文我认为必须用于获取资源
首先,您要创建目录名称值-“印地语”(类似于印地语),而不是在此目录中写入“ hi”和相同的字符串文件名副本,并且在按钮等操作中设置以下代码后,更改值不会更改参数。
Locale myLocale = new Locale("hi");
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = myLocale;
res.updateConfiguration(conf, dm);
Intent refresh = new Intent(Home.this, Home.class);
startActivity(refresh);
finish();
conf.locale
已弃用
private void setLanguage(String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Configuration config = new Configuration();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
config.setLocale(locale);
} else {
config.locale = locale;
}
getResources().updateConfiguration(config,
getResources().getDisplayMetrics());
}
在示例中,我们设置英语:
Configuration config = GetBaseContext().getResources().getConfiguration();
Locale locale = new Locale("en");
Locale.setDefault(locale);
config.locale = locale;
GetBaseContext().getResources().updateConfiguration(config,
GetBaseContext().getResources().getDisplayMetrics());
请记住,只有在“设备”系统中也找到了语言,这不仅适用于应用程序
对于阿拉伯语/ RTL支持
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(updateBaseContextLocale(newBase));
}
public Context updateBaseContextLocale(Context context) {
String language = SharedPreference.getInstance().getValue(context, "lan");//it return "en", "ar" like this
if (language == null || language.isEmpty()) {
//when first time enter into app (get the device language and set it
language = Locale.getDefault().getLanguage();
if (language.equals("ar")) {
SharedPreference.getInstance().save(mContext, "lan", "ar");
}
}
Locale locale = new Locale(language);
Locale.setDefault(locale);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
updateResourcesLocale(context, locale);
return updateResourcesLocaleLegacy(context, locale);
}
return updateResourcesLocaleLegacy(context, locale);
}
@TargetApi(Build.VERSION_CODES.N)
private Context updateResourcesLocale(Context context, Locale locale) {
Configuration configuration = context.getResources().getConfiguration();
configuration.setLocale(locale);
return context.createConfigurationContext(configuration);
}
@SuppressWarnings("deprecation")
private Context updateResourcesLocaleLegacy(Context context, Locale locale) {
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
configuration.locale = locale;
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
return context;
}