Reputation: 386
I'm developing and application with multiple activities. One of them is the "Settings" activity, which have an option to change the app language.
Here is how I handle the change language in the Settings activity:
final ListPreference language = (ListPreference) findPreference("language");
language.setSummary(Utils.getStringPreferences(context, "not-found", "language", Utils.USER_PREFS));
language.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (newValue.toString().equals("English"))
Utils.setStringPreferences(context, "English", "language", Utils.USER_PREFS);
else if (newValue.toString().equals("Español"))
Utils.setStringPreferences(context, "Español", "language", Utils.USER_PREFS);
analysis_performance.setSummary(newValue.toString());
restartActivity();
return false;
}
});
This is the function that I'm using to change the language, invoked in all activities before "setContentView(R.layout.layout);" method:
public static void updateLanguage(Context context) {
String language = getStringPreferences(context, "not-found", "language", USER_PREFS);
String country = null;
if (!"not-found".equals(language)) {
if ("English".equals(language)) {
language = "en";
country = "US";
} else if ("Español".equals(language)) {
language = "es";
country = "ES";
}
Locale locale = new Locale(language, country);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
context.getResources().updateConfiguration(config, null);
}
}
Apparently it works, but only for some activities. If I want to make all the activities have the same language I have to restart the app after I've used the above function.
This is the navigation between activities:
- MainActivity
- Settings
- Activity_1
- Activity_2
Activities correctly changed the language: Activity_1 and Activity_2
Activities not changed the language: MainActivity and Settings
The SettingsActivity:
Context context;
private AppCompatDelegate mDelegate;
List<String> allLaunchers;
List<String> allLaunchersPackages;
BrowserSpinnerAdapter adapter;
private final String TAG = Settings.class.getSimpleName();
Resources res;
@Override
protected void onCreate(Bundle savedInstanceState) {
getDelegate().installViewFactory();
getDelegate().onCreate(savedInstanceState);
super.onCreate(savedInstanceState);
Utils.updateLanguage(this);
setContentView(R.layout.activity_settings);
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
addPreferencesFromResource(R.xml.settings);
context = this;
res = getResources();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Display navigation button
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
final ListPreference browser_selection = (ListPreference) findPreference("browser_analysis");
fillBrowserSelection();
browser_selection.setSummary(allLaunchers.get(allLaunchersPackages.indexOf(Utils.getStringPreferences(context, "not-found", "browser", Utils.USER_PREFS))));
browser_selection.setEntries(allLaunchers.toArray(new CharSequence[allLaunchers.size()]));
browser_selection.setEntryValues(allLaunchersPackages.toArray(new CharSequence[allLaunchersPackages.size()]));
browser_selection.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
Utils.setStringPreferences(context, newValue.toString(), "browser", Utils.USER_PREFS);
browser_selection.setSummary(allLaunchers.get(allLaunchersPackages.indexOf(newValue.toString())));
return false;
}
});
final ListPreference security_level = (ListPreference) findPreference("security_level");
security_level.setSummary(Utils.getIntPreferences(context, -1, "security_level", Utils.USER_PREFS)+"");
security_level.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
Utils.setIntPreferences(context, Integer.parseInt(newValue.toString()), "security_level", Utils.USER_PREFS);
security_level.setSummary(newValue.toString());
return false;
}
});
final ListPreference analysis_performance = (ListPreference) findPreference("performance");
analysis_performance.setSummary(Utils.getStringPreferences(context, "not-found", "performance", Utils.USER_PREFS));
analysis_performance.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
Utils.setStringPreferences(context, newValue.toString(), "performance", Utils.USER_PREFS);
analysis_performance.setSummary(newValue.toString());
return false;
}
});
final ListPreference language = (ListPreference) findPreference("language");
language.setSummary(Utils.getStringPreferences(context, "not-found", "language", Utils.USER_PREFS));
language.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (newValue.toString().equals("English"))
Utils.setStringPreferences(context, "English", "language", Utils.USER_PREFS);
else if (newValue.toString().equals("Español"))
Utils.setStringPreferences(context, "Español", "language", Utils.USER_PREFS);
language.setSummary(newValue.toString());
Utils.updateLanguage(Settings.this);
recreate();
return false;
}
});
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.i(TAG, "onConfigurationChanged");
getBaseContext().getResources().updateConfiguration(newConfig, getBaseContext().getResources().getDisplayMetrics());
setContentView(R.layout.activity_settings);
setTitle(R.string.title_activity_settings);
// Checks the active language
if (newConfig.locale == Locale.ENGLISH) {
Toast.makeText(this, "English", Toast.LENGTH_SHORT).show();
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
public ActionBar getSupportActionBar() {
return getDelegate().getSupportActionBar();
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
getDelegate().onPostCreate(savedInstanceState);
}
@Override
public void setContentView(@LayoutRes int layoutResID) {
getDelegate().setContentView(layoutResID);
}
@Override
protected void onPostResume() {
super.onPostResume();
getDelegate().onPostResume();
}
@Override
protected void onStop() {
super.onStop();
getDelegate().onStop();
}
@Override
protected void onDestroy() {
super.onDestroy();
getDelegate().onDestroy();
}
private void setSupportActionBar(@Nullable Toolbar toolbar) {
getDelegate().setSupportActionBar(toolbar);
}
private AppCompatDelegate getDelegate() {
if (mDelegate == null) {
mDelegate = AppCompatDelegate.create(this, null);
}
return mDelegate;
}
SOLUTION !!!
After being in a chat with Rasi we finally solve this by creating this method to fill the layout components, as he recommended in option 1 (option 2 was also a way to solve this but I prefer this way so the user don't have to navigate in the app):
private void fillSettings() {
setContentView(R.layout.activity_settings);
setTitle(R.string.title_activity_settings);
setPreferenceScreen(null);
addPreferencesFromResource(R.xml.settings);
context = this;
res = getResources();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Display navigation button
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
final ListPreference browser_selection = (ListPreference) findPreference("browser_analysis");
fillBrowserSelection();
browser_selection.setSummary(allLaunchers.get(allLaunchersPackages.indexOf(Utils.getStringPreferences(context, "not-found", "browser", Utils.USER_PREFS))));
browser_selection.setEntries(allLaunchers.toArray(new CharSequence[allLaunchers.size()]));
browser_selection.setEntryValues(allLaunchersPackages.toArray(new CharSequence[allLaunchersPackages.size()]));
browser_selection.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
Utils.setStringPreferences(context, newValue.toString(), "browser", Utils.USER_PREFS);
browser_selection.setSummary(allLaunchers.get(allLaunchersPackages.indexOf(newValue.toString())));
return false;
}
});
final ListPreference security_level = (ListPreference) findPreference("security_level");
security_level.setSummary(Utils.getIntPreferences(context, -1, "security_level", Utils.USER_PREFS)+"");
security_level.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
Utils.setIntPreferences(context, Integer.parseInt(newValue.toString()), "security_level", Utils.USER_PREFS);
security_level.setSummary(newValue.toString());
return false;
}
});
final ListPreference analysis_performance = (ListPreference) findPreference("performance");
performance = Utils.getStringPreferences(context, "not-found", "performance", Utils.USER_PREFS);
if (performance.equals(Utils.FOREGROUND)) analysis_performance.setSummary(res.getString(R.string.text_foreground));
else if (performance.equals(Utils.BACKGROUND)) analysis_performance.setSummary(res.getString(R.string.text_background));
analysis_performance.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (newValue.equals(res.getString(R.string.text_foreground))) performance = Utils.FOREGROUND;
else if (newValue.equals(res.getString(R.string.text_background))) performance = Utils.BACKGROUND;
Utils.setStringPreferences(context, performance, "performance", Utils.USER_PREFS);
Log.i(TAG, performance);
analysis_performance.setSummary(newValue.toString());
return false;
}
});
final ListPreference language = (ListPreference) findPreference("language");
language.setSummary(Utils.getStringPreferences(context, "not-found", "language", Utils.USER_PREFS));
language.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (newValue.toString().equals("English"))
Utils.setStringPreferences(context, "English", "language", Utils.USER_PREFS);
else if (newValue.toString().equals("Español"))
Utils.setStringPreferences(context, "Español", "language", Utils.USER_PREFS);
language.setSummary(newValue.toString());
updateLanguage(Settings.this);
fillSettings();
return false;
}
});
}
And use it in the "onCreate" like this:
@Override
protected void onCreate(Bundle savedInstanceState) {
getDelegate().installViewFactory();
getDelegate().onCreate(savedInstanceState);
super.onCreate(savedInstanceState);
fillSettings();
}
Upvotes: 2
Views: 2075
Reputation: 10625
You have write code to change language in a onCreate()
method. So If you come back to your MainActivity
and SettingsActivity
after changing language it won't reflect because onCreate()
will never call for the activities which are coming from stack. Either you have to take advantage of onResume()
method of Activity
.
But still you won't able to see the changed values on UI because View is already drawn on screen. Now you have to two options according to me -
onResume()
and redraw view or initialise string resources again. Make sure to call a method directly from an Activity which is changing Locale because onResume()
will not call of that Activity
.onCreate()
will work.onConfigurationChanged()
and check there locale is changed or not. If locale changed then reload new strings.Upvotes: 2