2

I have a multi-language app whose Locale is changed programmatically.

When the application is first created, it looks into a specific SharedPreferences file and set the locale accordingly.

Then the user can go into a specific Activity P and choose among the available languages (now only two languages are available).

This is what I do in P, with lang being a String:

// set locale to that chosen by the user
((MyApp) getApplication()).setMyAppLocale(lang); 

// get the Locale object
Locale locale = ((MyApp) getApplication()).getMyAppLocale();

// classic code
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
      getBaseContext().getResources().getDisplayMetrics());

// clear the activity stack and restart the MainActivity
Intent intent = new Intent(this, MainActivity.class);
Bundle extras = new Bundle();
extras.putBoolean(MainActivity.PARAM_DO_RESTART, true);
intent.putExtras(extras);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();

The activity MainActivity receives a new Intent and does this:

@Override
public void onNewIntent(Intent anotherIntent) {
    super.onNewIntent(anotherIntent);
    setIntent(anotherIntent);
}

@Override
protected void onResume() {
    super.onResume();

    Intent intent = getIntent();
    Bundle extras = intent.getExtras();
    if(extras != null) {
        if (extras.getBoolean(PARAM_DO_RESTART, false)) {
            intent.putExtra(PARAM_DO_RESTART, false);
            setIntent(intent);
            finish();
            startActivity(intent);
        }
    } // if extras != null

In this way, MainActivity's onCreate is called again and the resources loaded again in the new Locale.

Everything is ok, but one thing.

All the strings appear in the correct locale, but the titles of all the activities stay in the language they were first created when the app was launched. They did not change. My activities are actually instances of ActionBarActivity and the titles are shown in SupportActionBar.

Question: how can I force those titles to be changed according to the current Locale?

Note: A simple solution is to call getSupportActionBar().setTitle(getString(R.string.title_activity_X)); for every Activity X. However, since there are quite a few activities I would rather find a way to have it done automagically.

Note: I am using API Level 19, with support library v7.

Antonio Sesto
  • 2,868
  • 5
  • 33
  • 51

2 Answers2

0

According to this answer the title is read only, so you should specify the title manually and cannot do it automatically. My guess is because it uses resource specified in AndroidManifest.xml which cannot be changed dynamically.

Community
  • 1
  • 1
Yurets
  • 3,999
  • 17
  • 54
  • 74
  • That is the problem, but it is a bug or should be considered so. The title is not read-only. There is a way to do it automatically, I will add the answer as soon as I am allowed to. – Antonio Sesto Apr 25 '15 at 16:42
  • unfortunately, I couldn't find any docs about that, but in my opinion it cannot be done as same as in `manifest` there are other labels, for example `Theme`, cannot be changed unless you call `setTheme()`. I add this question to favorite, I'd like to read the answer if you will find the trick. Cheers :) – Yurets Apr 25 '15 at 16:45
0

I have found a way in the answer provided by MiroM to this question on StackOverflow. Add the following code to your base Activity class, wherever it is best suited.

PackageManager pm = getPackageManager();
    try {
        ActivityInfo ai = pm.getActivityInfo(this.getComponentName(), PackageManager.GET_ACTIVITIES|PackageManager.GET_META_DATA);
        if (ai.labelRes != 0) {
            getSupportActionBar().setTitle(ai.labelRes);
        }
    } catch (PackageManager.NameNotFoundException e) {
        e.stacktrace();
    }

I hope someone else will reach this question and provide a more general way of doing this. This method is really useful when your activities have a common superclass, which was my case, but it is not true in general.

Community
  • 1
  • 1
Antonio Sesto
  • 2,868
  • 5
  • 33
  • 51
  • 1
    good one. also for making it more general I think it is possible to put this method in `BaseActivity.class` extended from `ActionBarActivity` so all other activities extended from `BaseActivity` will have same behavior. – Yurets Apr 26 '15 at 16:30