124 votes

Comment changer la langue de l'application lorsque l'utilisateur la sélectionne ?

Je veux que mon application supporte trois langues : espagnol, portugais et anglais. Et donner l'option de sélectionner la langue dans l'application.

1) 3 dossiers dessinables : dessinable-es, dessinable-pt, dessinable.

2) 3 dossiers de valeurs values-es,values-pt,values.Changez les valeurs de String.xml selon les langues.

J'ai une imageView qui permet de sélectionner la langue. Lorsque l'on clique dessus, un menu s'ouvre qui comprend les options anglais, espagnol et portugais.

J'ai défini le Locale à l'intérieur de l'application sur la sélection de l'option par ce code

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

J'ai déclaré à Manifest- Android:configChanges="locale"

Il fonctionne mais il y a quelques problèmes.

Problème :-

1) Lorsque la langue est sélectionnée, l'écran qui contient l'image de la sélection de la langue ne change pas mais les autres écrans changent.

2) Après le changement d'orientation, l'application rétablit la langue en fonction de la localisation du téléphone.

188voto

Udhay Points 332

C'est un extrait pour la page web : http://Android.programmerguru.com/Android-localization-at-runtime/

Il est simple de changer la langue de votre application lorsque l'utilisateur la sélectionne dans la liste des langues. Mettez en place une méthode comme ci-dessous qui accepte la locale comme chaîne (comme 'en' pour l'anglais, 'hi' pour l'hindi), configurez la locale pour votre application et rafraîchissez votre activité actuelle pour refléter le changement de langue. La locale que vous avez appliquée ne sera pas modifiée jusqu'à ce que vous la changiez à nouveau manuellement.

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

Assurez-vous que vous avez importé les paquets suivants :

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; 

ajouter le manifeste à l'activité Android:configChanges="locale|orientation"

12voto

Lokesh Tiwari Points 6168

Tout le code de @Uday est parfait mais il ne manque qu'une chose (la configuration par défaut dans build.gradle).

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

}

Le mien ne fonctionnait pas parce que les langues n'étaient pas mentionnées dans le fichier de configuration (build.gradle).

 defaultConfig {
    resConfigs "en", "hi", "kn"
}

après cela, toutes les langues ont commencé à fonctionner

11voto

sud007 Points 1961

De bonnes solutions expliquées assez bien ici. Mais en voici une autre.

Créez votre propre CustomContextWrapper classe prolongeant ContextWrapper et l'utiliser pour changer le paramètre Locale pour l'application complète. Voici une GIST avec l'usage.

Et ensuite, appelez le CustomContextWrapper avec l'identifiant local enregistré, par exemple 'hi' pour la langue hindi dans la méthode du cycle de vie des activités attachBaseContext . Utilisation ici :

@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(MyContextWrapper.wrap(newBase, language));
}

6voto

Frane Poljak Points 94

Vous devez soit supprimer android:configChanges="locale" du manifeste, ce qui entraînera le rechargement de l'activité, ou de passer outre onConfigurationChanged méthode :

@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
}

5voto

Solution Kotlin utilisant l'extension de contexte

fun Context.applyNewLocale(locale: Locale): Context {
    val config = this.resources.configuration
    val sysLocale = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        config.locales.get(0)
    } else {
        //Legacy
        config.locale
    }
    if (sysLocale.language != locale.language) {
        Locale.setDefault(locale)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            config.setLocale(locale)
        } else {
            //Legacy
            config.locale = locale
        }
        resources.updateConfiguration(config, resources.displayMetrics)
    }
    return this
}

Utilisation

override fun attachBaseContext(newBase: Context?) {
    super.attachBaseContext(newBase?.applyNewLocale(Locale("es", "MX")))
}

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