Как изменить язык приложения, когда пользователь выбирает язык?

Я хочу, чтобы мое приложение поддерживало три языка: испанский, португальский и английский. И дать возможность выбрать язык в приложении. Я сделал

1) 3 папки для рисования drawable-es, drawable-pt, drawable.

2) 3 значения папки значения-es, values-pt, values.Change String.xml значения в соответствии с языками.

У меня есть imageView для выбора языка. При нажатии на него открывается меню, которое состоит из опции английский, испанский, португальский.

Я установил Locale внутри приложения на выбор опции по этому коду

public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.en:
             Locale locale = new Locale("en"); 
             Locale.setDefault(locale);
             Configuration config = new Configuration();
             config.locale = locale;
             getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
             Toast.makeText(this, "Locale in English !", Toast.LENGTH_LONG).show();
             break;

        case R.id.pt:
             Locale locale2 = new Locale("pt"); 
             Locale.setDefault(locale2);
             Configuration config2 = new Configuration();
             config2.locale = locale2;
             getBaseContext().getResources().updateConfiguration(config2, getBaseContext().getResources().getDisplayMetrics());

             Toast.makeText(this, "Locale in Portugal !", Toast.LENGTH_LONG).show();
             break;

        case R.id.es:
             Locale locale3 = new Locale("es"); 
             Locale.setDefault(locale3);
             Configuration config3 = new Configuration();
             config3.locale = locale3;
             getBaseContext().getResources().updateConfiguration(config3, getBaseContext().getResources().getDisplayMetrics());

             Toast.makeText(this, "Locale in Spain !", Toast.LENGTH_LONG).show();
             break;     
    }
    return super.onOptionsItemSelected(item);
}

Я объявил в Manifest- android: configChanges = "locale"

Это работает, но есть некоторые проблемы.

Проблема: -

1) Когда выбран язык, экран, который состоит из изображения выбора языка, не изменяется, а другие экраны меняются.

2) После изменения ориентации приложение восстанавливает язык в соответствии с локалью телефона.

Ответ 1

Выдержка для веб-страницы: http://android.programmerguru.com/android-localization-at-runtime/

Это просто изменить язык вашего приложения, когда пользователь выбирает его из списка языков. Используйте метод, подобный приведенному ниже, который принимает языковой стандарт как String (например, "en" для английского языка, "hi" для хинди), настройте языковой стандарт для своего приложения и обновите текущую активность, чтобы отразить изменение языка. Примененный языковой стандарт не будет изменен, пока вы не измените его вручную.

public void setLocale(String lang) { 
    Locale myLocale = new Locale(lang); 
    Resources res = getResources(); 
    DisplayMetrics dm = res.getDisplayMetrics(); 
    Configuration conf = res.getConfiguration(); 
    conf.locale = myLocale; 
    res.updateConfiguration(conf, dm); 
    Intent refresh = new Intent(this, AndroidLocalize.class); 
    finish();
    startActivity(refresh); 
} 

Убедитесь, что вы импортировали следующие пакеты:

import java.util.Locale; 
import android.os.Bundle; 
import android.app.Activity; 
import android.content.Intent; 
import android.content.res.Configuration; 
import android.content.res.Resources; 
import android.util.DisplayMetrics; 

добавить в манифест к действию android: configChanges = "locale | ориентация"

Ответ 2

Вы должны либо удалить android:configChanges="locale" из манифеста, что приведет к перезагрузке активности, либо переопределить метод onConfigurationChanged:

@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
    // your code here, you can use newConfig.locale if you need to check the language
    // or just re-set all the labels to desired string resource
}

Ответ 3

Хорошие решения объясняются довольно хорошо здесь. Но вот еще один.

Создайте свой собственный класс CustomContextWrapper, расширяющий ContextWrapper, и используйте его для изменения настроек локали для всего приложения. Вот GIST с использованием.

А затем вызовите CustomContextWrapper с сохраненным идентификатором локали, например, 'hi' для языка хинди в методе жизненного цикла деятельности attachBaseContext. Использование здесь:

@Override
protected void attachBaseContext(Context newBase) {
    // fetch from shared preference also save the same when applying. Default here is en = English
    String language = MyPreferenceUtil.getInstance().getString("saved_locale", "en");
    super.attachBaseContext(SnapContextWrapper.wrap(newBase, language));
}

Ответ 4

весь вышеприведенный код идеален, но только один из них отсутствует, мой не работал только потому, что язык не был упомянут в файле конфигурации

 defaultConfig {

    resConfigs "en", "hi", "kn"

}

после этого все языки начали работать

Ответ 5

Пример кода Udhay работает хорошо. За исключением вопроса о Софиане Хассайни и Чираге Соланки, для повторного входа это не работает. Я пытаюсь вызвать код Udhay без перезапуска активности в onCreate(), перед super.onCreate(saveInstanceState) ;. Тогда все в порядке! Лишь небольшая проблема, строки меню по-прежнему не изменены в соответствии с установленным языком.

    public void setLocale(String lang) { //call this in onCreate()
      Locale myLocale = new Locale(lang); 
      Resources res = getResources(); 
      DisplayMetrics dm = res.getDisplayMetrics(); 
      Configuration conf = res.getConfiguration(); 
      conf.locale = myLocale; 
      res.updateConfiguration(conf, dm); 
      //Intent refresh = new Intent(this, AndroidLocalize.class); 
      //startActivity(refresh); 
      //finish();
    } 

Ответ 6

Те, кто получает версию, попробуют этот код..

public static void switchLocal(Context context, String lcode, Activity activity) {
        if (lcode.equalsIgnoreCase(""))
            return;
        Resources resources = context.getResources();
        Locale locale = new Locale(lcode);
        Locale.setDefault(locale);
        android.content.res.Configuration config = new 
        android.content.res.Configuration();
        config.locale = locale;
        resources.updateConfiguration(config, resources.getDisplayMetrics());
        //restart base activity 
        activity.finish();
        activity.startActivity(activity.getIntent());
    }