When user changes language i execute following code,it works fine for the present fragment in the activity, but if i go to other fragment, it partially updates the language, some strings gets updated and shows old language, and most importantly the date does not changes in inner fragments,and other activities.
I tested this in nougat, marshmallow and oreo, and its happening in all of OS.
When user changes the language i execute following.
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);
}
Method for post marshmallow OS.
@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);
}
Pre Nougat
@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;
}
In each activity, i execute following code.
@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" />
I assume that you are using this approach. Where its not suggested any change in the AndroidManifest.xml
so the android:configChanges="locale"
may cause the misbehavior you defined.
For the date formating you should take into consideration that your application is not using the Locale.getDefault()
but something different that is defined by the user and your LocaleHelper
mechanism.
Some extra details about config change
The android:configChanges
means you don't want the system to recreate your activity when one of the provided attribute happens. In your case the locale
.
In terms of development with that approach in order to properly handle this option in the manifest you have to implement the
@Override
public void onConfigurationChanged(Configuration newConfig) {
// refresh your views here
super.onConfigurationChanged(newConfig);
}
and then perform your own handling. Something that you didn't required in your case.