安卓Oreo中的RTL布局错误

7
自从我在移动设备上升级到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;
}

你在清单文件中启用了RTL吗? - Samuel Robert
@SamuelRobert:是的 android:supportsRtl="true" - Usman Ghauri
@SamuelRobert:只是为了澄清事实,一切都按预期正常工作,即使在Oreo以下的设备上也可以进行RTL布局转换,但在Oreo设备上却不能。 - Usman Ghauri
尝试从开发者选项启用强制RTL。 - nomag
@nomag:已经完成了。强制RTL可以正常工作,但这个不行。 - Usman Ghauri
尝试这个:https://dev59.com/C1kS5IYBdhLWcg3wiXbI - nomag
2个回答

17

在您的onCreate函数中进行简单的修复,添加以下代码:

if (Locale.getDefault().getLanguage()=="ar")
     getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
else
     getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_LTR);

2
谢谢您的想法!我们最终采用了更通用的版本:getWindow().getDecorView().setLayoutDirection(getResources().getConfiguration().getLayoutDirection()); - gmk57

5
感谢@amorenew,并修改了Util类的方法以支持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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接