177 votes

Définir le Locale de façon programmatique

Mon application supporte 3 (bientôt 4) langues. Comme plusieurs langues sont assez similaires, j'aimerais donner à l'utilisateur la possibilité de changer de langue dans mon application. Par exemple, un Italien pourrait préférer l'espagnol à l'anglais.

Existe-t-il un moyen pour l'utilisateur de choisir parmi les paramètres linguistiques disponibles pour l'application et de modifier ensuite le paramètre utilisé ? Je ne vois pas de problème à définir la locale pour chaque activité, car il s'agit d'une tâche simple à réaliser dans une classe de base.

1 votes

Si vous avez besoin d'un moyen de restaurer ultérieurement la locale par défaut ou si vous avez besoin d'une préférence linguistique contenant une liste de langues, et si vous voulez changer la locale de manière plus pratique, cela peut être utile : github.com/delight-im/Android-Languages

8voto

Burak Dizlek Points 3217

Il existe un moyen très simple.

dans BaseActivity, Activity ou Fragment override attachBaseContext

 override fun attachBaseContext(context: Context) {
    super.attachBaseContext(context.changeLocale("tr"))
}

extension

fun Context.changeLocale(language:String): Context {
    val locale = Locale(language)
    Locale.setDefault(locale)
    val config = this.resources.configuration
    config.setLocale(locale)
    return createConfigurationContext(config)
}

6voto

Hadid Graphics Points 137

Ajoutez une classe d'aide avec la méthode suivante :

public class LanguageHelper {
    public static final void setAppLocale(String language, Activity activity) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            Resources resources = activity.getResources();
            Configuration configuration = resources.getConfiguration();
            configuration.setLocale(new Locale(language));
            activity.getApplicationContext().createConfigurationContext(configuration);
        } else {
            Locale locale = new Locale(language);
            Locale.setDefault(locale);
            Configuration config = activity.getResources().getConfiguration();
            config.locale = locale;
            activity.getResources().updateConfiguration(config,
                    activity.getResources().getDisplayMetrics());
        }

    }
}

Et appelez-le dans votre activité de démarrage, comme MainActivity.java :

public void onCreate(Bundle savedInstanceState) {
    ...
    LanguageHelper.setAppLocale("fa", this);
    ...
}

5voto

nnyerges Points 423

Valable pour API16 à API28 Il suffit de placer cette méthode à un endroit quelconque :

Context newContext = context;

Locale locale = new Locale(languageCode);
Locale.setDefault(locale);

Resources resources = context.getResources();
Configuration config = new Configuration(resources.getConfiguration());

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
    config.setLocale(locale);
    newContext = context.createConfigurationContext(config);
} else {
    config.locale = locale;
    resources.updateConfiguration(config, resources.getDisplayMetrics());
}

return newContext;

Insérez ce code dans toutes vos activités en utilisant :

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(localeUpdateResources(base, "<-- language code -->"));
    }

ou appelez localeUpdateResources sur les fragments, adaptateurs, etc. où vous avez besoin du nouveau contexte.

Crédits : Yaroslav Berezanskyi

4voto

Makvin Points 857

Simple et facile

Locale locale = new Locale("en", "US");
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = locale;
res.updateConfiguration(conf, dm);

où "en" est le code de la langue et "US" le code du pays.

4voto

Sam Lu Points 827

J'ai trouvé le androidx.appcompat:appcompat:1.1.0 Le bogue peut également être corrigé en appelant simplement getResources() sur applyOverrideConfiguration()

@Override public void
applyOverrideConfiguration(Configuration cfgOverride)
{
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
      Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
    // add this to fix androidx.appcompat:appcompat 1.1.0 bug
    // which happens on Android 6.x ~ 7.x
    getResources();
  }

  super.applyOverrideConfiguration(cfgOverride);
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X