android关于切换语言
2025-04-08 本文已影响0人
吉凶以情迁
语言的api很简单, 但是 因为android有2个上下文 , 全局和activity上下文,如果要生效的话,我发现要同时调用两者,否则要么fragment里面不生效要么act里面没生效。
val which = SPUtils.getValue(SuperContext.getInstance(), "language", 0)
var language = ""
if (which == 1) {
language = "zh"
} else if (which == 2) {
language = "en"
}
if (!TextUtils.isEmpty(language)) {
LanguageSelectAdapter.applyLocale(SuperContext.getInstance(), language)
LanguageSelectAdapter.applyLocale(this, language)
}
public static Context applyLocale(Context context, String language) {
Locale locale;
if (language.equals("en")) {
locale = Locale.ENGLISH;
} else if (language.equals("zh")) {
locale = Locale.SIMPLIFIED_CHINESE;
} else if (language.equals("")) {
locale = Locale.getDefault();
} else {
if (language == null || language.isEmpty()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
LocaleList locales = Resources.getSystem().getConfiguration().getLocales();
if (locales.isEmpty()) {
locale = new Locale("");
} else {
locale = locales.get(0); // follow system
}
} else {
locale = Resources.getSystem().getConfiguration().locale;
}
} else {
locale = new Locale(language);
}
}
Locale.setDefault(locale);
Resources resources = context.getResources();
Configuration config = resources.getConfiguration();
config.setLocale(locale);
resources.updateConfiguration(config, resources.getDisplayMetrics());
return context;
}
上面代码在splash入口写就行,
而 act 设置的地方这样写 发现就能全部生效了
LanguageSelectAdapter.applyLocale(SuperContext.getInstance(), language);
LanguageSelectAdapter.applyLocale(getActivity(), language);
getActivity().recreate();
再次优化
String languageStr = SPUtils.getValue(SuperContext.getInstance(), "languageStr", "");
LanguageSelectAdapter.Bean[] items = ModuleManager.getInstance().getSupportLangeuages();
int currentChooseLanguage = 0;
for (int i = 0; i < items.length; i++) {
LanguageSelectAdapter.Bean item = items[i];
if (item.value.equals(languageStr)) {
currentChooseLanguage = i;
break;
}
}
LanguageSelectAdapter arrayAdapter = new LanguageSelectAdapter(
getActivity(), R.layout.view_language_item, items);
int finalCurrentLanguage = currentChooseLanguage;
builder.setSingleChoiceItems(arrayAdapter, currentChooseLanguage, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
LanguageSelectAdapter.Bean item = items[which];
SPUtils.setValue(SuperContext.getInstance(), "languageStr", item.value);
LanguageSelectAdapter.applyLocale(SuperContext.getInstance(), item.value);
LanguageSelectAdapter.applyLocale(getActivity(), item.value);
getActivity().recreate();
}
});
builder.setTitle(AppContext.getStr(R.string.language_setting));
builder.show();
public com.sotrun.app.adapter.LanguageSelectAdapter.Bean[] getSupportLangeuages() {
LanguageSelectAdapter.Bean[] items = new LanguageSelectAdapter.Bean[]{
new LanguageSelectAdapter.Bean(SuperContext.getStr(R.string.default_), ""),
new LanguageSelectAdapter.Bean(SuperContext.getStr(R.string.chinese), "zh"),
new LanguageSelectAdapter.Bean("English", "en"),
};
return items;
}
但是这样还有一个问题,我发现横屏等触发act重布局的情况下又会回复,光在splash设置一次代码还不够。故依然无法偷懒只能baseact全部执行。
另外 对于act 在xml定义的title,那么这种界面就需要在act具体界面重新设置标题了。 mainifest.xml中定义的不会被刷新。