Changing Locale: Force Activity to Reload Resources

Changing locale: Force activity to reload resources?

In your AndroidManifest.xml, add this attribute to your Activity

android:configChanges="locale"

In your activity override onConfigurationChanged()

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

https://developer.android.com/guide/topics/manifest/activity-element.html#config

How to refresh activity after changing language (Locale) inside application

After changing language newly created activities display with changed new language, but current activity and previously created activities which are in pause state are not updated.How to update activities ?

Pre API 11 (Honeycomb), the simplest way to make the existing activities to be displayed in new language is to restart it. In this way you don't bother to reload each resources by yourself.

private void restartActivity() {
Intent intent = getIntent();
finish();
startActivity(intent);
}

Register an OnSharedPreferenceChangeListener, in its onShredPreferenceChanged(), invoke restartActivity() if language preference was changed. In my example, only the PreferenceActivity is restarted, but you should be able to restart other activities on activity resume by setting a flag.

Update (thanks @stackunderflow): As of API 11 (Honeycomb) you should use recreate() instead of restartActivity().

public class PreferenceActivity extends android.preference.PreferenceActivity implements
OnSharedPreferenceChangeListener {

// ...

@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals("pref_language")) {
((Application) getApplication()).setLocale();
restartActivity();
}
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}

@Override
protected void onStop() {
super.onStop();
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}
}

I have a blog post on this topic with more detail, but it's in Chinese. The full source code is on github: PreferenceActivity.java

reload views after changing the locale in android

I guess you are asking how to "reload" the Activity you are on when changing the locale.

As far as I know, you have to re-layout / recreate the Views or re-set the text in them. If, however, you find a better solution, please share it.

Forcing a different locale works only for top activity in back stack

The problem may be coming from the fact that the boolean Globals.language_changed is static, and therefore when languageCheck is called from the top activity, this boolean becomes false before languageCheck is called from the back activity. You might put in some checks to see if Activit(ies) earlier in the hierarchy are open, and if so keep the boolean set as true in case the user presses the Back button. Another option would be some logic that reloads all open Activities at once when the new locale is selected.

-- EDIT --
On further examination, I don't think this is quite your problem, since you are also updating the boolean in onStart for each activity (I missed this part when I read it the first time). Perhaps the locale changed when one of the Activities higher in the stack changed it, but the Activities lower in the stack just need to refresh. Does an orientation change on one of the lower Activities change it from English to Norwegian?

-- EDIT 2 --
The easiest way to check if that is the problem, would be to add some logging into Globals.checkLocale to see whether or not this conditional statement is true:

if( !config.locale.equals( locale ) )

If that turns out to be the problem, then one possible solution would be to save a local Locale instance in each Activity rather than a global one, and compare to that one. For example, you could grab a Locale instance in each Activity's onCreate method:

myLocale = getBaseContext().getResources().getConfiguration().locale;

Then, instead of calling Globals.checkLocal, just do the following conditional statement (in each Activity's languageCheck method):

if( Globals.locale != null && !Globals.locale.equals( myLocale ) )
{
Configuration config = getBaseContext().getResources().getConfiguration();
config.locale = Globals.locale;
getBaseContext().getResources().updateConfiguration( config, null );
Intent restart = getIntent();
finish();
startActivity( restart );
}

Upon restarting, the Activity's onCreate method would get called again, which would update myLocale to the correct value. This is just a quick solution, not necessarily the best one.. you could expand on this to move some of that code into a method in Globals if you wanted for example, or use a different location than onCreate to get the local Locale instance for each Activity.



Related Topics



Leave a reply



Submit