I'm trying to implement app language switch on the runtime, once the user made language changes in app preferences. I have this code in my PreferenceFragment:
public class Fragment_Preferences extends PreferenceFragment {
private SharedPreferences.OnSharedPreferenceChangeListener prefListener;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
prefListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
Log.i("Pref changed", "Settings key changed: " + key);
if(key.equals("language_preference"))
{
String system_language = Locale.getDefault().getLanguage().toUpperCase();
String preference_language = Common_Methods.get_preference_language(getActivity());
Toast.makeText(getActivity(), "Pref changed: "+preference_language, Toast.LENGTH_SHORT).show();
Common_Methods.set_app_interface_language(getActivity(), system_language, preference_language);
}
}
};
prefs.registerOnSharedPreferenceChangeListener(prefListener);
}
}
This is my set_app_interface_language
method in Common_Methods
class:
public static void set_app_interface_language(Context context, String system_language, String preference_language)
{
if(!preference_language.equals(system_language))
{
Locale locale = new Locale(preference_language.toLowerCase());
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
}
}
I get the Toast message when I change language in preferences. I know that this method works since I call it also from my Fragment_Main. But the language doesn't change on the runtime - I have to exit the app and reopen it, only then I see the changes.
So how can I make the app language change on the runtime, without restarting the app? Thanks!
OK, I think I solved this problem: I call for Common_Methods.set_app_interface_language
not in SharedPreferences.OnSharedPreferenceChangeListener
, but rather in onRestart
method of my Fragment_Main.
I also changed set_app_interface_language
to return new config. And once it's returned - I pass it to onConfigurationChanged
method to recreate fragment. Now, I did ran into Performing pause of activity that is not resumed...
error message once my device's screen turned off. After googling a little about it, I realized that it's non-fatal exception, but I still used Handler to postpone recreate()
for 1 millisecond and let the Fragment restart properly. I also set another method in my Common_Methods
to check if there were any changes made to the app language and recreate the fragment only if the method returns true; I call this method in onRestart
That gave the app some performance boost, since now there's no need to recreate the fragment every time the app restarts.