我正在尝试在Spinner
的{{1}}中的两种语言之间切换:“英语”和“法语”。
我有我的Activity
文件夹和values
文件夹,在这些文件夹中有一个名为values-fr
的文件,其中包含我要即时翻译的一项活动的字符串。
对于string_my_activity.xml
,我目前在普通的strings.xml中用一个字符串数组填充它(稍后将进行翻译)。
我一直在使用来自StackOverflow的样本,说使用Spinner
或LocaleHelper
。但是,两者都不起作用。我认为问题是我如何使用它们,就像其他人一样成功。
当我尝试在CustomContextWrapper
的{{1}}中使用它们时,显然没有任何反应。我在活动上执行了onItemSelected
,但是当前所有字符串仍然是默认语言。
我正在使用Spinner
:
recreate()
和ContextWrapper
:
public class CustomContextWrapper extends ContextWrapper {
public CustomContextWrapper(Context base) {
super(base);
}
@SuppressWarnings("deprecation")
public static ContextWrapper wrap(Context context, String language) {
Configuration config = context.getResources().getConfiguration();
Locale sysLocale;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
sysLocale = getSystemLocale(config);
} else {
sysLocale = getSystemLocaleLegacy(config);
}
if (!language.equals("") && !sysLocale.getLanguage().equals(language)) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
setSystemLocale(config, locale);
} else {
setSystemLocaleLegacy(config, locale);
}
context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
}
return new ContextWrapper(context);
}
@SuppressWarnings("deprecation")
public static Locale getSystemLocaleLegacy(Configuration config) {
return config.locale;
}
@TargetApi(Build.VERSION_CODES.N)
public static Locale getSystemLocale(Configuration config) {
return config.getLocales().get(0);
}
@SuppressWarnings("deprecation")
public static void setSystemLocaleLegacy(Configuration config, Locale locale) {
config.locale = locale;
}
@TargetApi(Build.VERSION_CODES.N)
public static void setSystemLocale(Configuration config, Locale locale) {
config.setLocale(locale);
}
}
但是他们两个都无法正常工作。
在我的LocaleHelper
中,我像这样使用它们:
public class LocaleHelper {
private static final String TAG = LocaleHelper.class.getSimpleName();
private static final String SELECTED_LANGUAGE = "Locale.Helper.Selected.Language";
public static final String DEFAULT_LANGUAGE = "en";
public static Context onAttach(Context context) {
Log.d(TAG, "onAttach(context)");
String lang = getStoredLanguage(context, Locale.getDefault().getLanguage());
// String lang = getStoredLanguage(context, DEFAULT_LANGUAGE);
return setLocale(context, lang);
}
public static Context onAttach(Context context, String defaultLanguage) {
Log.d(TAG, "onAttach(context, language)");
String lang = getStoredLanguage(context, defaultLanguage);
return setLocale(context, lang);
}
public static String getLanguage(Context context) {
return getStoredLanguage(context, Locale.getDefault().getLanguage());
}
public static Context setLocale(Context context, String language) {
Log.d(TAG, "Setting locale: " + language);
saveLanguage(context, language);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return updateResources(context, language);
}
return updateResourcesLegacy(context, language);
}
private static String getStoredLanguage(Context context, String defaultLanguage) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
return preferences.getString(SELECTED_LANGUAGE, defaultLanguage);
}
private static void saveLanguage(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) {
Log.d(TAG, "updateResources::" + language);
Locale locale = new Locale(language);
Locale.setDefault(locale);
Resources resources = context.getResources();
Log.d(TAG, "updateResources:: Getting config");
Configuration configuration = resources.getConfiguration();
configuration.setLocale(locale);
configuration.setLayoutDirection(locale);
Log.d(TAG, "updateResources:: Creating config context");
return context.createConfigurationContext(configuration);
}
@SuppressWarnings("deprecation")
private static Context updateResourcesLegacy(Context context, String language) {
Log.d(TAG, "updateResourcesLegacy");
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.LOLLIPOP) {
configuration.setLayoutDirection(locale);
}
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
return context;
}
public static Locale getLocale(Configuration config) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return getSystemLocale(config);
} else {
return getSystemLocaleLegacy(config);
}
}
@SuppressWarnings("deprecation")
private static Locale getSystemLocaleLegacy(Configuration config) {
return config.locale;
}
@TargetApi(Build.VERSION_CODES.N)
private static Locale getSystemLocale(Configuration config) {
return config.getLocales().get(0);
}
}
我能得到的最好的语言是显示在日志中的语言,但没有反映在UI中。目前,它似乎总是获得默认语言“ en”,这是另一个问题。
所以我的问题是,如何获取UI进行自我更新? 谢谢。
答案 0 :(得分:0)
我在互联网上找到了此代码,对我来说,它工作得很好,看看它是否也可以解决您的问题,请根据您的微调器进行修改
languagebutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
LocaleManager.setNewLocale(language.this, LocaleManager.LANGUAGE_KEY_ENGLISH);
String languageToLoad = LocaleManager.LANGUAGE_KEY_ENGLISH; // your language
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
try {
ActivityInfo info = getPackageManager().getActivityInfo(getComponentName(), GET_META_DATA);
if (info.labelRes != 0) {
setTitle(info.labelRes);
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
});
LocaleManager.java
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;
public class LocaleManager {
/**
* For english locale
*/
public static final String LANGUAGE_KEY_ENGLISH = "en";
/**
* for hindi locale
*/
public static final String LANGUAGE_KEY_HINDI = "hi";
/***
* // for spanish locale
*/
private static final String LANGUAGE_KEY = "language_key";
/**
* set current pref locale
* @param mContext
* @return
*/
public static Context setLocale(Context mContext) {
return updateResources(mContext, getLanguagePref(mContext));
}
/**
* Set new Locale with context
* @param mContext
* @param mLocaleKey
* @return
*/
public static Context setNewLocale(Context mContext, String mLocaleKey) {
setLanguagePref(mContext, mLocaleKey);
return updateResources(mContext, mLocaleKey);
}
/**
* Get saved Locale from SharedPreferences
* @param mContext current context
* @return current locale key by default return english locale
*/
public static String getLanguagePref(Context mContext) {
SharedPreferences mPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
return mPreferences.getString(LANGUAGE_KEY, LANGUAGE_KEY_ENGLISH);
}
/**
* set pref key
* @param mContext
* @param localeKey
*/
private static void setLanguagePref(Context mContext, String localeKey) {
SharedPreferences mPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
mPreferences.edit().putString(LANGUAGE_KEY, localeKey).commit();
}
/**
* update resource
* @param context
* @param language
* @return
*/
private static Context updateResources(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Resources res = context.getResources();
Configuration config = new Configuration(res.getConfiguration());
if (Build.VERSION.SDK_INT >= 17) {
config.setLocale(locale);
context = context.createConfigurationContext(config);
} else {
config.locale = locale;
res.updateConfiguration(config, res.getDisplayMetrics());
}
return context;
}
/**
* get current locale
* @param res
* @return
*/
public static Locale getLocale(Resources res) {
Configuration config = res.getConfiguration();
return Build.VERSION.SDK_INT >= 24 ? config.getLocales().get(0) : config.locale;
}
}