Изменение локали во время выполнения, не затрагивающее фрагменты

1

Когда пользователь меняет язык, я выполняю следующий код, он отлично работает для текущего фрагмента в активности, но если я перехожу к другому фрагменту, он частично обновляет язык, некоторые строки обновляются и показывают старый язык, и, что наиболее важно, дата не изменения во внутренних фрагментах и другие виды деятельности.

Я проверил это в нуге, зефире и орео, и это происходит во всех ОС.

Когда пользователь меняет язык, я выполняю следующее.

 LocaleHelper.setLocale(getApplicationContext(), language);
 recreate();

LocalHelper

public static Context setLocale(Context context, String language) {
        persist(context, language);


        Log.d("LocaleSet", language);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return updateResources(context, language);
        }

        return updateResourcesLegacy(context, language);
    }

Метод пост-зефирной ОС.

   @TargetApi(Build.VERSION_CODES.N)
    private static Context updateResources(Context context, String language) {
        Locale locale = new Locale(language);
        Locale.setDefault(locale);

        Configuration configuration = context.getResources().getConfiguration();
        configuration.setLocale(locale);

        return context.createConfigurationContext(configuration);
    }

Пре нугат

@SuppressWarnings("deprecation")
    private static Context updateResourcesLegacy(Context context, String language) {
        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.JELLY_BEAN_MR1) {
            configuration.setLayoutDirection(locale);
        }

        resources.updateConfiguration(configuration, resources.getDisplayMetrics());

        return context;
    }

В каждом действии я выполняю следующий код.

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(LocaleHelper.onAttach(base, LocaleHelper.getLanguage(base)));
}

MainFest

<application
        android:name=".GlobalApplication"
        android:allowBackup="false"
        android:icon="@mipmap/app_icon"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/app_icon"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        android:windowSoftInputMode="adjustPan"
        tools:replace="android:allowBackup">

        <activity
            android:name=".activities.homeactivity.HomeActivity"
            android:label="@string/app_name"
            android:screenOrientation="portrait"
            android:configChanges="locale"
            android:theme="@style/AppTheme.NoActionBar" />

        <activity
            android:name=".activities.profilepageactivity.ProfilePageActivity"
            android:label="@string/title_activity_profile_page"
            android:screenOrientation="portrait"
            android:theme="@style/AppTheme.NoActionBar" />
Теги:
android-fragments
locale
android-layout

1 ответ

1
Лучший ответ

Я предполагаю, что вы используете этот подход. Там, где не предлагается никаких изменений в AndroidManifest.xml android:configChanges="locale" может вызвать неправильное поведение, которое вы определили.

Для форматирования даты вы должны принять во внимание, что ваше приложение не использует Locale.getDefault() а что-то другое, что определяется пользователем и вашим механизмом LocaleHelper.

Некоторые дополнительные подробности об изменении конфигурации

android:configChanges означает, что вы не хотите, чтобы система воссоздала вашу активность, когда происходит один из предоставленных атрибутов. В вашем случае locale.

С точки зрения разработки с этим подходом, чтобы правильно обработать эту опцию в манифесте, вы должны реализовать

@Override
public void onConfigurationChanged(Configuration newConfig) {
  // refresh your views here
  super.onConfigurationChanged(newConfig);
}

а затем выполнить свою собственную обработку. То, что вам не нужно в вашем случае.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню