android Oreo 中的 RTL 布局错误
RTL layout bug in android Oreo
自从我在移动设备上升级到 android oreo 后,我对应用程序的 RTL 支持就无法正常工作。它将字符串更改为阿拉伯语但不更改布局方向。但如果我 运行 将相同的 RTL 转移到任何低于 oreo 的设备,一切正常。还有其他人遇到过这个问题吗?关于此错误和解决方法是否有任何官方声明?
以下是我更改语言环境的方法
public static boolean setDefaultLocale(Context context) {
Resources resources = context.getResources();
PreferenceManager preferenceManager = PreferenceManager.getInstance();
String localLanguage = resources.getConfiguration().locale.getLanguage();
boolean isLanguageChanged = !preferenceManager.getCurrentLanguageCode().equalsIgnoreCase(localLanguage);
if (isLanguageChanged) {
Log.d("", preferenceManager.getCurrentLanguageCode());
Locale locale = new Locale(preferenceManager.getCurrentLanguageCode());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
Locale.setDefault(Locale.Category.DISPLAY, locale);
else
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
resources.updateConfiguration(config, resources.getDisplayMetrics());
((Activity) context).recreate();
}
return isLanguageChanged;
}
在 onCreate 函数中添加以下代码进行简单修复:
if (Locale.getDefault().getLanguage()=="ar")
getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
else
getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
感谢 @amorenew 并调整了 Util class 中的方法以支持 oreo 中的这个奇怪更新 下面是工作方法,您只需在用户更改应用程序语言首选项时调用此方法 onResume
/**
* this to change app language to the saved language in user preferences
*
* @param context
* @return
*/
public static boolean setDefaultLocale(Context context, boolean isClearData) {
Resources resources = context.getResources();
Resources resourcesApp = context.getApplicationContext().getResources();
String localLanguage = resources.getConfiguration().locale.getLanguage();
boolean isLanguageChanged = !PreferenceManager.getInstance().getCurrentLanguageCode().equalsIgnoreCase(localLanguage);
if (isLanguageChanged) {
Log.d("", PreferenceManager.getInstance().getCurrentLanguageCode());
Locale locale = new Locale(PreferenceManager.getInstance().getCurrentLanguageCode());
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
resources.updateConfiguration(config, resources.getDisplayMetrics());
resourcesApp.updateConfiguration(config, resources.getDisplayMetrics());
//for API 25
Configuration configuration = resources.getConfiguration();
configuration.setLocale(locale);
context.getApplicationContext().createConfigurationContext(configuration);
context.createConfigurationContext(configuration);
((Activity) context).recreate();
if (isClearData) {
CurrencyViewModel.getInstance().removeModel();
CarNationalityViewModel.getInstance().removeModel();
DialCodeViewModel.getInstance().removeModel();
}
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
((Activity)context).getWindow().getDecorView().setLayoutDirection(Locale.getDefault().getLanguage().equalsIgnoreCase("ar")
? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR);
}
}
return isLanguageChanged;
}
自从我在移动设备上升级到 android oreo 后,我对应用程序的 RTL 支持就无法正常工作。它将字符串更改为阿拉伯语但不更改布局方向。但如果我 运行 将相同的 RTL 转移到任何低于 oreo 的设备,一切正常。还有其他人遇到过这个问题吗?关于此错误和解决方法是否有任何官方声明?
以下是我更改语言环境的方法
public static boolean setDefaultLocale(Context context) {
Resources resources = context.getResources();
PreferenceManager preferenceManager = PreferenceManager.getInstance();
String localLanguage = resources.getConfiguration().locale.getLanguage();
boolean isLanguageChanged = !preferenceManager.getCurrentLanguageCode().equalsIgnoreCase(localLanguage);
if (isLanguageChanged) {
Log.d("", preferenceManager.getCurrentLanguageCode());
Locale locale = new Locale(preferenceManager.getCurrentLanguageCode());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
Locale.setDefault(Locale.Category.DISPLAY, locale);
else
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
resources.updateConfiguration(config, resources.getDisplayMetrics());
((Activity) context).recreate();
}
return isLanguageChanged;
}
在 onCreate 函数中添加以下代码进行简单修复:
if (Locale.getDefault().getLanguage()=="ar")
getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
else
getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
感谢 @amorenew 并调整了 Util class 中的方法以支持 oreo 中的这个奇怪更新 下面是工作方法,您只需在用户更改应用程序语言首选项时调用此方法 onResume
/**
* this to change app language to the saved language in user preferences
*
* @param context
* @return
*/
public static boolean setDefaultLocale(Context context, boolean isClearData) {
Resources resources = context.getResources();
Resources resourcesApp = context.getApplicationContext().getResources();
String localLanguage = resources.getConfiguration().locale.getLanguage();
boolean isLanguageChanged = !PreferenceManager.getInstance().getCurrentLanguageCode().equalsIgnoreCase(localLanguage);
if (isLanguageChanged) {
Log.d("", PreferenceManager.getInstance().getCurrentLanguageCode());
Locale locale = new Locale(PreferenceManager.getInstance().getCurrentLanguageCode());
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
resources.updateConfiguration(config, resources.getDisplayMetrics());
resourcesApp.updateConfiguration(config, resources.getDisplayMetrics());
//for API 25
Configuration configuration = resources.getConfiguration();
configuration.setLocale(locale);
context.getApplicationContext().createConfigurationContext(configuration);
context.createConfigurationContext(configuration);
((Activity) context).recreate();
if (isClearData) {
CurrencyViewModel.getInstance().removeModel();
CarNationalityViewModel.getInstance().removeModel();
DialCodeViewModel.getInstance().removeModel();
}
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
((Activity)context).getWindow().getDecorView().setLayoutDirection(Locale.getDefault().getLanguage().equalsIgnoreCase("ar")
? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR);
}
}
return isLanguageChanged;
}