Изменение языка приложения во время выполнения

Я пытаюсь реализовать переключение языка приложения во время выполнения, как только пользователь изменил язык в настройках приложения. У меня есть этот код в моем 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);
}

}

Это мой метод set_app_interface_language в классе Common_Methods:

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());
    }
}

Я получаю всплывающее сообщение, когда меняю язык в настройках. Я знаю, что этот метод работает, так как я вызываю его также из моего Fragment_Main. Но язык не меняется во время выполнения - мне нужно выйти из приложения и снова открыть его, только тогда я вижу изменения.

Итак, как я могу изменить язык приложения во время выполнения, не перезапуская приложение? Спасибо!


person Igal    schedule 12.07.2014    source источник
comment
Можете ли вы просто попробовать один раз. получить активность (). воссоздать ()   -  person prabhat    schedule 12.07.2014
comment
Я пытался сделать это в своем OnSharedPreferenceChangeListener, но ничего не происходит, все тот же язык...   -  person Igal    schedule 12.07.2014
comment
сделайте это в методе onConfigurationChanged(..)   -  person prabhat    schedule 12.07.2014
comment
в манифесте добавить onConfigChanged=locale для текущей активности   -  person prabhat    schedule 12.07.2014
comment
Хорошо, я сделал свой set_app_interface_language return config и внутри своего Fragment_Preferences я создал метод onConfigurationChange и вызвал его из OnSharedPreferenceChangeListener. Это изменило язык моего меню «Параметры», но не всего приложения. Также, когда я добавил configChange="locale" в файл manifest. Итак, что мне нужно сделать, чтобы изменить язык всего приложения?   -  person Igal    schedule 13.07.2014


Ответы (1)


Хорошо, я думаю, что решил эту проблему: я вызываю Common_Methods.set_app_interface_language не в SharedPreferences.OnSharedPreferenceChangeListener, а в onRestart методе моего Fragment_Main.

Я также изменил set_app_interface_language, чтобы вернуть новую конфигурацию. И как только он возвращается - я передаю его методу onConfigurationChanged для воссоздания фрагмента. Теперь я столкнулся с сообщением об ошибке Performing pause of activity that is not resumed..., когда экран моего устройства выключился. Немного погуглив об этом, я понял, что это не фатальное исключение, но я все же использовал обработчик, чтобы отложить recreate() на 1 миллисекунду и позволить фрагменту перезапуститься должным образом. Я также установил другой метод в моем Common_Methods, чтобы проверить, были ли внесены какие-либо изменения в язык приложения, и воссоздать фрагмент, только если метод возвращает true; Я называю этот метод в onRestart. Это дало приложению некоторый прирост производительности, так как теперь нет необходимости заново создавать фрагмент каждый раз, когда приложение перезагружается.

person Igal    schedule 13.07.2014