Mes utilisateurs peuvent modifier les paramètres régionaux dans l'application (ils peuvent vouloir conserver les paramètres de leur téléphone en anglais mais lire le contenu de mon application en français, néerlandais ou toute autre langue ...)
Pourquoi cela fonctionne-t-il parfaitement bien en 1.5 / 1.6 mais PAS en 2.0 plus ???
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case 201:
Locale locale2 = new Locale("fr");
Locale.setDefault(locale2);
Configuration config2 = new Configuration();
config2.locale = locale2;
getBaseContext().getResources().updateConfiguration(
config2, getBaseContext().getResources().getDisplayMetrics());
// loading data ...
refresh();
// refresh the tabs and their content
refresh_Tab ();
break;
case 201: etc...
Le problème est que le MENU "rétrécit" de plus en plus chaque fois que l'utilisateur parcourt les lignes de code ci-dessus ...
Voici le menu qui se réduit:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, 100, 1, "REFRESH").setIcon(android.R.drawable.ic_menu_compass);
SubMenu langMenu = menu.addSubMenu(0, 200, 2, "NL-FR").setIcon(android.R.drawable.ic_menu_rotate);
langMenu.add(1, 201, 0, "Nederlands");
langMenu.add(1, 202, 0, "Français");
menu.add(0, 250, 4, R.string.OptionMenu2).setIcon(android.R.drawable.ic_menu_send);
menu.add(0, 300, 5, R.string.OptionMenu3).setIcon(android.R.drawable.ic_menu_preferences);
menu.add(0, 350, 3, R.string.OptionMenu4).setIcon(android.R.drawable.ic_menu_more);
menu.add(0, 400, 6, "Exit").setIcon(android.R.drawable.ic_menu_delete);
return super.onCreateOptionsMenu(menu);
}
Que dois-je faire dans l'API niveau 5 pour que cela fonctionne à nouveau?
VOICI LE CODE COMPLET SI VOUS VOULEZ TESTER CECI:
import java.util.Locale;
import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.widget.Toast;
public class Main extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
SubMenu langMenu = menu.addSubMenu(0, 200, 2, "NL-FR").setIcon(android.R.drawable.ic_menu_rotate);
langMenu.add(1, 201, 0, "Nederlands");
langMenu.add(1, 202, 0, "Français");
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case 201:
Locale locale = new Locale("nl");
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
Toast.makeText(this, "Locale in Nederlands !", Toast.LENGTH_LONG).show();
break;
case 202:
Locale locale2 = new Locale("fr");
Locale.setDefault(locale2);
Configuration config2 = new Configuration();
config2.locale = locale2;
getBaseContext().getResources().updateConfiguration(config2, getBaseContext().getResources().getDisplayMetrics());
Toast.makeText(this, "Locale en Français !", Toast.LENGTH_LONG).show();
break;
}
return super.onOptionsItemSelected(item);
}
}
ET VOICI LE MANIFESTE:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cousinHub.ChangeLocale"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".Main"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="3" />
</manifest>
C'EST CE QUE J'AI TROUVÉ:
<uses-sdk android:minSdkVersion="5" />
=> IL FONCTIONNE JUSTE FIN ...
<uses-sdk android:minSdkVersion="3" />
=> Le menu rétrécit à chaque fois que vous modifiez les paramètres régionaux !!!
comme je veux garder mon application accessible aux utilisateurs sur 1.5, que dois-je faire ??
Réponses:
Grâce à la question d'origine, il ne s'agit pas exactement des paramètres régionaux eux-mêmes, toutes les autres questions liées aux paramètres régionaux font référence à celle-ci. C'est pourquoi je voulais clarifier la question ici. J'ai utilisé cette question comme point de départ pour mon propre code de commutation locale et j'ai découvert que la méthode n'était pas exactement correcte. Cela fonctionne, mais uniquement jusqu'à tout changement de configuration (par exemple, rotation de l'écran) et uniquement dans cette activité particulière. Jouer avec un code pendant un certain temps, je me suis retrouvé avec l'approche suivante:
J'ai étendu android.app.Application et ajouté le code suivant:
Ce code garantit que chaque activité aura un ensemble de paramètres régionaux personnalisé et ne sera pas réinitialisé lors de la rotation et d'autres événements.
J'ai également passé beaucoup de temps à essayer d'apporter la modification des préférences à appliquer immédiatement, mais sans succès: la langue a changé correctement au redémarrage de l'activité, mais les formats numériques et les autres propriétés locales n'ont été appliqués qu'au redémarrage complet de l'application.
Modifications apportées à
AndroidManifest.xml
N'oubliez pas d'ajouter
android:configChanges="layoutDirection|locale"
à chaque activité sur AndroidManifest, ainsi qu'àandroid:name=".MyApplication"
l'<application>
élément.la source
config
etnewConfig
). Vous devez d'abord en faire une copieconfig = new Configuration(config);
. Je viens de passer une heure à déboguer ce code avant de découvrir le problème (cela faisait clignoter l'activité à l'infini).updateConfiguration()
fonctionne, donc parfois votre activité sera affichée dans 2 langues différentes (en particulier dans les boîtes de dialogue). Plus d'infos: stackoverflow.com/questions/39705739/…Après une bonne nuit de sommeil, j'ai trouvé la réponse sur le Web (une simple recherche Google sur la ligne suivante "
getBaseContext().getResources().updateConfiguration(mConfig, getBaseContext().getResources().getDisplayMetrics());
"), la voici:texte du lien => ce lien montre également
screenshots
ce qui se passe!La densité était le problème ici , je devais l'avoir dans le AndroidManifest.xml
Le plus important est l' androïde: anyDensity = "true" .
N'oubliez pas d'ajouter ce qui suit dans
AndroidManifest.xml
chaque activité (pour Android 4.1 et ci-dessous):Cette version est nécessaire lorsque vous créez une explication pour Android 4.2 (API niveau 17) ici :
la source
activity.recreate()
Dans Android M, la meilleure solution ne fonctionnera pas. J'ai écrit une classe d'assistance pour corriger ce que vous devez appeler à partir de votre classe Application et de toutes les activités (je suggère de créer une BaseActivity et de faire en sorte que toutes les activités en héritent.
Remarque : Cela prendra également en charge correctement la direction de mise en page RTL.
Classe d'assistance:
Application:
BaseActivity:
la source
BaseActivity()
constructeur ne devrait-il pas appelersuper()
?<application android:name=".App">
en manifeste? Que diriez-vous d'ajouterandroid:configChanges="layoutDirection|locale"
à chaque activité du manifeste?C'est pour mon commentaire sur la réponse d'Andrey mais je ne peux pas inclure de code dans les commentaires.
Votre activité préférée est-elle appelée de votre activité principale? vous pouvez le placer dans le CV ...
la source
activity.recreate()
recreate()
méthode si l' utilisationrecreate()
à la place derefresh()
votre code. Cela permettra d'économiser vos 3 lignes de code dans larefresh()
méthodeJe ne pouvais pas utiliser Android: anyDensity = "true" car les objets de mon jeu seraient positionnés de manière complètement différente ... cela semble aussi faire l'affaire:
la source
code Locale.setDefault(mLocale); Configuration config = getBaseContext().getResources().getConfiguration(); if (!config.locale.equals(mLocale)) { config.locale = mLocale; getBaseContext().getResources().updateConfiguration(config, null); }
Si vous souhaitez appliquer immédiatement les options de menu pour modifier les paramètres régionaux, vous devez procéder comme suit.
la source
onMenuOpened
ne devrait être appelé qu'une seule fois, après un changement de paramètres régionaux.