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


106

Je souhaite que mon application prenne en charge trois langues: espagnol, portugais et anglais. Et donnez la possibilité de sélectionner la langue dans l'application.

1) 3 dossiers à dessiner drawable-es, drawable-pt, drawable.

2) Dossier à 3 valeurs values-es, values-pt, values.Changez les valeurs de String.xml en fonction des langues.

J'ai imageView pour sélectionner la langue.Lorsque vous cliquez dessus, le menu s'ouvre qui comprend l'option anglais, espagnol, portugais.

J'ai défini les paramètres régionaux dans l'application lors de la sélection d'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é dans Manifest- android: configChanges = "locale"

Cela fonctionne mais il y a un problème.

Problème:-

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

2) Après l'orientation, changez la langue de restauration de l'application en fonction des paramètres régionaux du téléphone.


1
Pour le 2ème problème, essayez d'ajouter: android:configChanges="locale"pour votre activité dans le fichier AndroidManifest.xml
Parth Doshi

J'ai déjà ajouté toutes les activités de mon manifeste.
mukesh

Vous pouvez utiliser la bibliothèque suivante, qui fournit la liste des langues, les préférences pour votre écran de paramètres et remplace la langue de votre application: github.com/delight-im/Android-Languages
caw

Réponses:


172

C'est un extrait de 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. Ayez une méthode comme ci-dessous qui accepte les paramètres régionaux sous forme de chaîne (comme «en» pour l'anglais, «hi» pour l'hindi), configurez les paramètres régionaux de votre application et actualisez votre activité actuelle pour refléter le changement de langue. Les paramètres régionaux que vous avez appliqués ne seront pas modifiés tant que vous ne les modifiez pas à 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 d'avoir importé les packages 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"


2
Oui bien sûr. Je peux fournir l'extrait de la page Web. Où j'ai besoin de fournir s'il vous plaît laissez-moi savoir. Merci.
Udhay

3
Assurez-vous d'ajouter finish () pour ne pas avoir deux copies de votre activité dans la pile de navigation.
Joel Teply

6
finish()doit être appelé avant startActivity(refresh). Sinon, l'application peut quitter au lieu de redémarrer l'activité.
Mohammed Ali

10
Salut, je l'ai fait, ça marche, mais quand je redémarre l'application, elle revient à la langue par défaut ..
Sofiane Hassaini

5
Configuration config = nouvelle configuration (newConfig); config.locale = locale; Dans mon cas, recevoir ce message. locale obsolète au niveau de l'API 25
Milon

9

Les bonnes solutions expliquées assez bien ici. Mais en voici un de plus.

Créez votre propre CustomContextWrapperextension de classe ContextWrapperet utilisez-la pour modifier les paramètres régionaux de l'application complète. Voici un GIST avec l'utilisation.

Et puis appelez l' CustomContextWrapperidentificateur de paramètres régionaux avec, par exemple, 'hi'pour la langue hindi dans la méthode du cycle de vie de l'activité 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));
}

Merci pour le lien , il fonctionne , mais je ne comprenais pas quelques choses, je viens d' appeler l' MyContextWrapper.warpen onAttachd'un seul fragment de mon application , mais la langue a été modifié pour l'application entière, mais les titres d'activité sont restés inchangés, je pense que ce est parce que les titres du manifeste ont la priorité, mais si j'appelle la même méthode dans onAttachBaseContexma sous-classe d'application, les titres d'activité changent également dans la langue sélectionnée, mais alors les modifications ne sont appliquées qu'au fragment que j'ai appelé dans la méthode warp, pourquoi ?
Abhinav Chauhan

@AbhinavChauhan Je ne suis pas sûr que cela soit vrai. J'ai besoin de vérifier celui-là. Je n'ai jamais rencontré ce problème lorsque j'ai implémenté cette solution. Cependant, cela fait longtemps et il peut y avoir des changements dans l'implémentation Android pour les versions plus récentes. Vous pouvez également essayer les réponses les plus récentes sur ce post.
sud007

J'ai essayé de nombreuses solutions mais aucune d'entre elles n'a fonctionné ou peut-être les ai-je mises en œuvre de manière incorrecte, que votre classe fonctionne bien avec les activités, je l'utilise warpdans onAttachle fragment, auparavant j'ai dit que j'avais juste besoin de le faire avec le fragment de l'activité principale et la langue changée en l'application entière, c'est vrai, mais pour tous les autres fragments, la langue change en anglais lors du changement de configuration, je dois donc insérer onattachtous les fragments et au lieu du manifeste, je définis les titres de la barre d'action dans le code, maintenant l'application fonctionne comme prévu. merci
Abhinav Chauhan

D'accord! Je suis sûr que vous n'avez pas à faire cela pour chaque écran, juste la première activité qui se lance et à l'intérieur de la attachBaseContextfonction uniquement. Et cela le fait pour tous les écrans. Avez-vous créé une «BaseActivity» pour toutes les activités de votre application?
sud007

Non, j'essayais de le faire dans ma sous-classe d'application en pensant qu'il sera appliqué à l'ensemble de l'application, puis à tous les fragments, mais il s'avère que le wrap()code doit être exécuté à chaque changement de configuration, alors je l'ai mis dans le Activité abstraite à partir de laquelle toutes les autres activités s'étendent, maintenant ça marche
Abhinav Chauhan

6

Vous devez soit supprimer android:configChanges="locale"du manifeste, ce qui entraînera le rechargement de l'activité, soit remplacer la onConfigurationChangedmé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
}

La suppression de android: configChanges = "locale" du manifeste n'empêche pas l'application de redémarrer. Il redémarrera indépendamment du fait que cela soit ajouté au manifeste ou non.
portfoliobuilder

Je ne dis pas que supprimer android: configChanges = "locale" du manifeste empêche l'application de redémarrer, je dis exactement le contraire. Maintenant, pour le cas où nous avons android: configChanges = "locale" dans le manifeste, cela empêchait l'application de se recharger au moment où j'ai écrit cette réponse, je ne peux pas dire avec certitude que c'est le cas maintenant.
Frane Poljak

6

tout le code ci-dessus @ Uday est parfait mais il ne manque qu'une seule chose (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 simplement 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


3
ça ne
marche

Est-ce vraiment nécessaire?
JCarlosR

1
@JCarlosR oui. quand j'ai ajouté des langues dans le fichier de configuration, le code d'Udhay a commencé à fonctionner
Lokesh Tiwari

3

Ceux qui rencontrent le problème de version essaient ce code.

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

2

L'exemple de code d'Udhay fonctionne bien. Sauf la question de Sofiane Hassaini et Chirag SolankI, pour la rentrée, ça ne marche pas. J'essaye d'appeler le code d'Udhay sans redémarrer l'activité dans onCreate (), avant super.onCreate (savedInstanceState) ;. Alors c'est OK! Seul petit problème, les chaînes de menu n'ont toujours pas été modifiées par les paramètres régionaux définis.

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

même problème avec les chaînes de menu. Résolvez-vous le problème?
AlexS

@AlexS, je n'ai pas trouvé de moyen de résoudre le problème dans la chaîne de menu. Mais trouvé pour quitter l'application, puis ressaisir, les chaînes de menu peuvent normalement être changées pour la nouvelle locale.
Fisher

tu veux dire Intent refresh = new Intent(this, ThisActivity.class); startActivity(refresh); ?
AlexS

2
@AlexS, non! l'ajout du nouvel Intent () et startActivity () peut le faire revenir à la langue par défaut lors du redémarrage de l'application. Ce que je veux dire, c'est que si les utilisateurs quittent l'application et entrent à nouveau dans l'application, les chaînes de menu peuvent être modifiées pour la nouvelle locale.
Fisher
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.