我已经阅读了有关在运行时更改应用内语言的所有内容。目前,对于API 26 + 27 + 28 + 29而言,所有内容都可以正常运行(是的,我已经测试了所有这些内容),并且在API 25及以下版本开始崩溃。 Now the only thing I know that happened in API level 26 was that application and activities no longer share the same resources (aka the top level resources) by default. And also that updateConfiguration for Resources gets deprecated in favor of createConfigurationContext in API 25
但这确实给了我零线索。
这是我的代码:
public class BaseApp extends MultiDexApplication { //for MinSDK < 21, otherwise "extends Application"
@Override
public void onCreate() {
LocaleHelper.updateResources(this);
super.onCreate();
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.updateResources(base));
MultiDex.install(this); /* Needed as per (@link MultiDexApplication) */
}
@Override
public void onConfigurationChanged(Configuration config) {
super.onConfigurationChanged(config);
LocaleHelper.updateResources(this);
}
基本活动:
public abstract class BaseActivity extends AppCompatActivity {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.updateResources(base));
}
Helper类:
class LocaleHelper {
static Context updateResources(Context context) {
Resources resources = context.getResources();
Configuration config = new Configuration(resources.getConfiguration());
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
String lang = preferences.getString(Constants.PREF_KEY_LOCALE_OVERRIDE, Constants.PREF_VALUE_LOCALE_SYSTEM);
Locale locale = new Locale(lang);
if (Build.VERSION.SDK_INT >= 17) {
config.setLocale(locale);
context = context.createConfigurationContext(config);
} else {
config.locale = locale;
resources.updateConfiguration(config, resources.getDisplayMetrics());
}
return context;
}
答案 0 :(得分:1)
这是AndroidX的AppCompat实现的已知错误。 该错误位于1.0.0版中:“ androidx.appcompat:appcompat:1.1.0” 我确认它可以在该库的1.2.0版本中使用。
答案 1 :(得分:0)
尝试:
private 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 (Utility.isAtLeastVersion(N)) {
setLocaleForApi24(config, locale);
context = context.createConfigurationContext(config);
} else if (Utility.isAtLeastVersion(JELLY_BEAN_MR1)) {
config.setLocale(locale);
context = context.createConfigurationContext(config);
} else {
config.locale = locale;
res.updateConfiguration(config, res.getDisplayMetrics());
}
return context;
}
@RequiresApi(api = N)
private void setLocaleForApi24(Configuration config, Locale target) {
Set<Locale> set = new LinkedHashSet<>();
// bring the target locale to the front of the list
set.add(target);
LocaleList all = LocaleList.getDefault();
for (int i = 0; i < all.size(); i++) {
// append other locales supported by the user
set.add(all.get(i));
}
Locale[] locales = set.toArray(new Locale[0]);
config.setLocales(new LocaleList(locales));
}
并查看此文章:https://proandroiddev.com/change-language-programmatically-at-runtime-on-android-5e6bc15c758
答案 2 :(得分:0)
为什么不使用https://github.com/YarikSOffice/lingver库。
除了该库之外,我还必须添加此行才能重新启动设置活动。
UtilLanguage.setLanguage(activity, position); //This is the line where I used library
activity.recreate();
此外,对于上一个活动(“设置”活动的Backstack),我存储了现有语言并检查resume方法的更改以更新我的主要活动;
@Override
public void onResume() {
if (selectedLanguageIndex != appPreferences.getPreferredApplicationLanguageIndex()) {
recreate();
}
}