Comment actualiser l’activité après avoir changé de langue (parameters régionaux) dans l’application

Les utilisateurs de mon application peuvent modifier la langue à partir des parameters de l’application. Est-il possible de changer la langue dans l’application sans avoir d’effet sur les parameters linguistiques généraux? Cette question de stackoverflow est très utile pour moi et je l’ai essayée. Après avoir modifié la langue, les activités nouvellement créées s’affichent avec la nouvelle langue, mais l’activité en cours et les activités précédemment créées qui sont en état de pause ne sont pas mises à jour. Comment mettre à jour les activités? J’ai également passé beaucoup de temps à essayer d’appliquer immédiatement le changement de préférence, mais sans succès. Lorsque l’application est redémarrée, toutes les activités créées à nouveau, donc maintenant la langue a changé correctement.

android:configChanges="locale" 

également ajouté au manifeste pour toutes les activités. et supporte également tous les écrans. Actuellement, je n’ai rien fait dans la méthode onResume () de l’activité. Existe-t-il un moyen d’actualiser ou de mettre à jour l’activité (sans terminer et recommencer)? Est-ce qu’il me manque quelque chose à faire dans la méthode onResume ()?

Après avoir modifié la langue, les activités nouvellement créées s’affichent avec la nouvelle langue, mais l’activité en cours et les activités précédemment créées qui sont en état de pause ne sont pas mises à jour. Comment mettre à jour les activités?

Pre API 11 (Honeycomb), le moyen le plus simple d’afficher les activités existantes dans une nouvelle langue est de le redémarrer. De cette façon, vous ne vous souciez pas de recharger chaque ressource par vous-même.

 private void restartActivity() { Intent intent = getIntent(); finish(); startActivity(intent); } 

Enregistrez un OnSharedPreferenceChangeListener , dans son onShredPreferenceChanged() , restartActivity() si la préférence de langue a été modifiée. Dans mon exemple, seule PreferenceActivity est redémarrée, mais vous devriez pouvoir redémarrer d’autres activités sur la reprise d’activité en définissant un indicateur.

Mise à jour (merci @stackunderflow): À partir de l’API 11 (Honeycomb), vous devez utiliser restartActivity() au lieu de restartActivity() .

 public class PreferenceActivity extends android.preference.PreferenceActivity implements OnSharedPreferenceChangeListener { // ... @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Ssortingng key) { if (key.equals("pref_language")) { ((Application) getApplication()).setLocale(); restartActivity(); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preferences); getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); } @Override protected void onStop() { super.onStop(); getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this); } } 

J’ai un article de blog sur ce sujet avec plus de détails, mais c’est en chinois. Le code source complet est sur github: PreferenceActivity.java

Si j’imaginais que vous définissiez android:configChanges dans manifest.xml et créer plusieurs répertoires pour plusieurs langages tels que: values-fr OR values-nl , je pourrais suggérer ce code (classe In Activity):

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button btn = (Button) findViewById(R.id.btn); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // change language by onclick a button Configuration newConfig = new Configuration(); newConfig.locale = Locale.FRENCH; onConfigurationChanged(newConfig); } }); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); getBaseContext().getResources().updateConfiguration(newConfig, getBaseContext().getResources().getDisplayMesortingcs()); setContentView(R.layout.main); setTitle(R.ssortingng.app_name); // Checks the active language if (newConfig.locale == Locale.ENGLISH) { Toast.makeText(this, "English", Toast.LENGTH_SHORT).show(); } else if (newConfig.locale == Locale.FRENCH){ Toast.makeText(this, "French", Toast.LENGTH_SHORT).show(); } } 

J’ai testé ce code, c’est correct.

Comme les ressources de chaîne ont déjà été chargées pour les parameters régionaux existants, les activités déjà ouvertes ne s’afficheront pas automatiquement à l’aide des chaînes de la nouvelle locale. La seule façon de résoudre ce problème est de recharger toutes les chaînes et de les définir à nouveau sur les vues. En règle générale, un appel à setContentView(...) sera en mesure de couvrir cela (en fonction de votre structure d’activité), mais bien sûr, cela a pour effet secondaire de perdre tout état d’affichage que vous aviez.

 public void onResume() { super.onResume(); ... if (localeHasChanged) { setContentView(R.layout.xxx); } ... } 

Vous ne voudrez probablement pas recharger les vues à chaque fois dans onResume() , mais uniquement lorsque les parameters régionaux ont été modifiés. Vérifier à localeHasChanged moment mettre à jour les vues (c’est-à-dire localeHasChanged ) consiste à propager l’événement de modification des parameters régionaux aux activités précédentes. Cela peut être fait de plusieurs manières, par exemple en utilisant l’état statique singleton-esque ou en conservant cet événement dans le stockage.

Vous pouvez également essayer de minimiser le nombre d’activités pouvant être ouvertes lorsque vous pouvez modifier les parameters régionaux, par exemple en faisant en sorte que la sélection se trouve dans l’un des écrans initiaux.

Pour Android 4.2 (API 17), vous devez utiliser android:configChanges="locale|layoutDirection" dans votre fichier AndroidManifest.xml. Voir onConfigurationchanged n’est pas appelé sur jellybean (4.2.1)

Vous pouvez utiliser recreate(); pour redémarrer votre activité lorsque la langue change.

J’utilise le code suivant pour redémarrer l’activité lorsque la langue change:

 SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this); Configuration config = getBaseContext().getResources().getConfiguration(); Ssortingng lang = settings.getSsortingng("lang_list", ""); if (! "".equals(lang) && ! config.locale.getLanguage().equals(lang)) { recreate(); //this is used for recreate activity Locale locale = new Locale(lang); Locale.setDefault(locale); config.locale = locale; getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMesortingcs()); } 

J’ai résolu mon problème avec ce code

 public void setLocale(Ssortingng lang) { myLocale = new Locale(lang); Resources res = getResources(); DisplayMesortingcs dm = res.getDisplayMesortingcs(); Configuration conf = res.getConfiguration(); conf.locale = myLocale; res.updateConfiguration(conf, dm); onConfigurationChanged(conf); } @Override public void onConfigurationChanged(Configuration newConfig) { iv.setImageDrawable(getResources().getDrawable(R.drawable.keyboard)); greet.setText(R.ssortingng.greet); textView1.setText(R.ssortingng.langselection); super.onConfigurationChanged(newConfig); } 

La façon dont nous l’avons fait était d’utiliser des émissions:

  1. Envoyer la diffusion chaque fois que l’utilisateur change de langue
  2. Enregistrez le récepteur de diffusion dans AppActivity.onCreate() et AppActivity.onDestroy() dans AppActivity.onDestroy()
  3. Dans BroadcastReceiver.onReceive() redémarrez simplement l’activité.

AppActivity est l’activité parente de toutes les autres sous-classes d’activités.


Vous trouverez ci-dessous l’extrait de mon code, non testé en dehors du projet, mais qui devrait vous donner une bonne idée.

Lorsque l’utilisateur change de langue

 sendBroadcast(new Intent("Language.changed")); 

Et dans l’activité parent

 public class AppActivity extends Activity { /** * The receiver that will handle the change of the language. */ private BroadcastReceiver mLangaugeChangedReceiver; @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ... // Other code here // ... // Define receiver mLangaugeChangedReceiver = new BroadcastReceiver() { @Override public void onReceive(final Context context, final Intent intent) { startActivity(getIntent()); finish(); } }; // Register receiver registerReceiver(mLangaugeChangedReceiver, new IntentFilter("Language.changed")); } @Override protected void onDestroy() { super.onDestroy(); // ... // Other cleanup code here // ... // Unregister receiver if (mLangaugeChangedReceiver != null) { try { unregisterReceiver(mLangaugeChangedReceiver); mLangaugeChangedReceiver = null; } catch (final Exception e) {} } } } 

Cela permettra également d’actualiser l’activité qui a changé la langue (si elle sous-classe l’activité ci-dessus).

Cela vous fera perdre toutes les données, mais si c’est important, vous devriez déjà vous en Actvity.onSaveInstanceState() utilisant Actvity.onSaveInstanceState() et Actvity.onRestoreInstanceState() (ou similaire).

Laissez-moi savoir vos pensées à ce sujet.

À votre santé!

Appelez cette méthode pour modifier les parameters régionaux de l’application:

 public void settingLocale(Context context, Ssortingng language) { Locale locale; Configuration config = new Configuration(); if(language.equals(LANGUAGE_ENGLISH)) { locale = new Locale("en"); Locale.setDefault(locale); config.locale = locale; }else if(language.equals(LANGUAGE_ARABIC)){ locale = new Locale("hi"); Locale.setDefault(locale); config.locale = locale; } context.getResources().updateConfiguration(config, null); // Here again set the text on view to reflect locale change // and it will pick resource from new locale tv1.setText(R.ssortingng.one); //tv1 is textview in my activity } 

Remarque: Placez vos chaînes dans value et valeurs-folder.