Reputation: 451
I'm trying to use Arabic and English in my app. Its working fine on devices running on android Nougat or below. But it's not working on oreo devices. Is there some new code requirement in API 26? I am using the code below.
public void changeLanguage(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Configuration config = context.getResources().getConfiguration();
config.setLocale(locale);
context.createConfigurationContext(config);
context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
}
and I'm passing "en" and "ar" as language argument.
Upvotes: 7
Views: 3374
Reputation: 3719
I recently faced issue related to layout direction on Oreo
. Resources were being updated but Layout direction not changing.
Below code worked for me.
public static void setRTLSupportIfRequired(AppCompatActivity activity) {
if(getLanguageFromPrefs(activity).equals("ar")) {
activity.getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
}else{
activity.getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
}
}
Note: Previously I were using View.LAYOUT_DIRECTION_LOCALE
but it was not working on Oreo
Upvotes: 2
Reputation: 11
Yes, there is issue with Android Oreo for language change(strings and layout direction in arabic,urdu and hebrew), i found the solution this will help you to solve this problem
In LanguageContextWrapper.java class
public static ContextWrapper wrap(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
configuration.setLocale(locale);
LocaleList localeList = new LocaleList(locale);
LocaleList.setDefault(localeList);
configuration.setLocales(localeList);
configuration.setLayoutDirection(locale);
context.createConfigurationContext(configuration);
} else {
configuration.locale = locale;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
configuration.setLayoutDirection(locale);
}
}
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
return new LanguageContextWrapper(context);
}
In activity class override following method
override fun attachBaseContext(base: Context) {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1) {
super.attachBaseContext(LanguageContextWrapper.wrap(base, Locale.getDefault().language))
} else {
super.attachBaseContext(base)
}
}
And after change language we have to recreate activity, we need to write following code
fun recreateActivity(){
if (Build.VERSION.SDK_INT in 26..27) {
if (Locale.getDefault().language == "ar" ||
Locale.getDefault().language == "iw" ||
Locale.getDefault().language == "ur")
window.decorView.layoutDirection = View.LAYOUT_DIRECTION_RTL
else
window.decorView.layoutDirection = View.LAYOUT_DIRECTION_LTR
}
recreate()
}
Upvotes: 1
Reputation: 667
I had same problem before and after some research I find out one solution. Create custom language aware context wrapper and attach on your activity's attachBaseContext() method.
@SuppressWarnings("NewApi")
public static LanguageAwareContext newLanguageAwareContext(String targetLanguage, Context context) {
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
Locale newLocale = new Locale(targetLanguage);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {
configuration.setLocale(newLocale);
LocaleList.setDefault(new LocaleList(newLocale));
context = context.createConfigurationContext(configuration);
} else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR1) {
configuration.setLocale(newLocale);
context = context.createConfigurationContext(configuration);
} else {
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
}
return new LanguageAwareContext(context);
}
override attachBaseContext method and change with your customized context wrapper
@Override
protected void attachBaseContext(Context newBase) {
newBase = LanguageAwareContext.newLanguageAwareContext("en",newBase);
super.attachBaseContext(newBase);
}
Upvotes: 1
Reputation: 180
Locale locale = new Locale(lang);
Locale.setDefault(locale);
Configuration config = new Configuration();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
config.setLocale(locale);
} else {
config.locale = locale;
}
context.getApplicationContext().getResources().updateConfiguration(config,
context.getApplicationContext().getResources().getDisplayMetrics());
This worked for me.
Upvotes: 1
Reputation: 4061
When you set new Locale
you should restart your Activity
. You can perform it using the next snippet of code:
private void restartActivity() {
Intent intent = getIntent();
finish();
startActivity(intent);
}
Then your changeLanguage()
method will look in a next way:
public void changeLanguage(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Configuration config = context.getResources().getConfiguration();
config.setLocale(locale);
context.createConfigurationContext(config);
context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
restartActivity();
}
Upvotes: 4