Когда пользователь меняет язык, я выполняю следующий код, он отлично работает для текущего фрагмента в активности, но если я перехожу к другому фрагменту, он частично обновляет язык, некоторые строки обновляются и показывают старый язык, и, что наиболее важно, дата не изменения во внутренних фрагментах и другие виды деятельности.
Я проверил это в нуге, зефире и орео, и это происходит во всех ОС.
Когда пользователь меняет язык, я выполняю следующее.
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" />
Я предполагаю, что вы используете этот подход. Там, где не предлагается никаких изменений в AndroidManifest.xml
android:configChanges="locale"
может вызвать неправильное поведение, которое вы определили.
Для форматирования даты вы должны принять во внимание, что ваше приложение не использует Locale.getDefault()
а что-то другое, что определяется пользователем и вашим механизмом LocaleHelper
.
Некоторые дополнительные подробности об изменении конфигурации
android:configChanges
означает, что вы не хотите, чтобы система воссоздала вашу активность, когда происходит один из предоставленных атрибутов. В вашем случае locale
.
С точки зрения разработки с этим подходом, чтобы правильно обработать эту опцию в манифесте, вы должны реализовать
@Override
public void onConfigurationChanged(Configuration newConfig) {
// refresh your views here
super.onConfigurationChanged(newConfig);
}
а затем выполнить свою собственную обработку. То, что вам не нужно в вашем случае.