Comment changer le thème actuel à l’exécution dans Android

J’ai créé une PreferenceActivity qui permet à l’utilisateur de choisir le thème qu’il souhaite appliquer à l’ensemble de l’application.

Lorsque l’utilisateur sélectionne un thème, ce code est exécuté:

if (...) { getApplication().setTheme(R.style.BlackTheme); } else { getApplication().setTheme(R.style.LightTheme); } 

Mais, même si j’ai vérifié avec le débogueur que le code est en cours d’exécution, je ne vois aucun changement dans l’interface utilisateur.

Les thèmes sont définis dans res/values/styles.xml et Eclipse n’indique aucune erreur.

       

Une idée de ce qui pourrait se passer et comment y remédier? Dois-je appeler setTheme à un point particulier du code? Mon application se compose de plusieurs activités si cela vous aide.

J’aimerais voir la méthode aussi, où vous définissez une fois pour toutes vos activités. Mais pour autant que je sache, vous devez définir chaque activité avant d’afficher des vues.

Pour référence, vérifiez ceci:

http://www.anddev.org/applying_a_theme_to_your_application-t817.html

Modifier (copié à partir de ce forum):

 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Call setTheme before creation of any(!) View. setTheme(android.R.style.Theme_Dark); // ... setContentView(R.layout.main); } 

Si vous voulez changer le thème d’une activité déjà existante, appelez setTheme() après setTheme() .

Note: n’appelez pas recréer si vous changez de thème dans onCreate() , pour éviter une boucle infinie.

recreate() (comme mentionné par TPReal ) ne fera que redémarrer l’activité en cours, mais les activités précédentes restront en arrière et le thème ne leur sera pas appliqué.

Donc, une autre solution à ce problème consiste à recréer complètement la stack de tâches, comme ceci:

  TaskStackBuilder.create(getActivity()) .addNextIntent(new Intent(getActivity(), MainActivity.class)) .addNextIntent(getActivity().getIntent()) .startActivities(); 

MODIFIER:

Il suffit de mettre le code ci-dessus après avoir effectué le changement de thème sur l’interface utilisateur ou ailleurs. Toutes vos activités doivent avoir la méthode setTheme() appelée avant onCreate() , probablement dans une activité parent. C’est également une approche normale pour stocker le thème choisi dans SharedPreferences , le lire et ensuite définir en utilisant la méthode setTheme() .

J’ai eu le même problème mais j’ai trouvé la solution.

 public class EditTextSmartPhoneActivity extends Activity implements DialogInterface.OnClickListener { public final static int CREATE_DIALOG = -1; public final static int THEME_HOLO_LIGHT = 0; public final static int THEME_BLACK = 1; int position; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { position = getIntent().getIntExtra("position", -1); switch(position) { case CREATE_DIALOG: createDialog(); break; case THEME_HOLO_LIGHT: setTheme(android.R.style.Theme_Holo_Light); break; case THEME_BLACK: setTheme(android.R.style.Theme_Black); break; default: } super.onCreate(savedInstanceState); setContentView(R.layout.main); } private void createDialog() { /** Options for user to select*/ Ssortingng choose[] = {"Theme_Holo_Light","Theme_Black"}; AlertDialog.Builder b = new AlertDialog.Builder(this); /** Setting a title for the window */ b.setTitle("Choose your Application Theme"); /** Setting items to the alert dialog */ b.setSingleChoiceItems(choose, 0, null); /** Setting a positive button and its listener */ b.setPositiveButton("OK",this); /** Setting a positive button and its listener */ b.setNegativeButton("Cancel", null); /** Creating the alert dialog window using the builder class */ AlertDialog d = b.create(); /** show dialog*/ d.show(); } @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub AlertDialog alert = (AlertDialog)dialog; int position = alert.getListView().getCheckedItemPosition(); finish(); Intent intent = new Intent(this, EditTextSmartPhoneActivity.class); intent.putExtra("position", position); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } } 

Nous devons définir le thème avant d’appeler la méthode ‘super.onCreate ()’ et ‘setContentView ()’ .

Consultez ce lien pour appliquer un nouveau thème à l’ensemble de l’application à l’exécution.

J’ai eu un problème similaire et j’ai résolu de cette façon ..

 @Override public void onCreate(Bundle savedInstanceState) { if (getIntent().hasExtra("bundle") && savedInstanceState==null){ savedInstanceState = getIntent().getExtras().getBundle("bundle"); } //add code for theme switch(theme) { case LIGHT: setTheme(R.style.LightTheme); break; case BLACK: setTheme(R.style.BlackTheme); break; default: } super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //code } 

Ce code sert à recréer le groupe de sauvegarde d’activité et à modifier le thème. Vous devez écrire votre propre onSaveInstanceState (Bundle outState); A partir d’API-11, vous pouvez utiliser la méthode recreate () à la place

 Bundle temp_bundle = new Bundle(); onSaveInstanceState(temp_bundle); Intent intent = new Intent(this, MainActivity.class); intent.putExtra("bundle", temp_bundle); startActivity(intent); finish(); 

C’est ce que j’ai créé pour Material Design. Puisse-t-il vous être utile.

Recherchez MultipleThemeMaterialDesign

Je sais que je suis en retard mais je voudrais poster une solution ici: Vérifiez le code source complet ici . C’est le code que j’ai utilisé lors du changement de thème en utilisant les préférences ..

 SharedPreferences pref = PreferenceManager .getDefaultSharedPreferences(this); Ssortingng themeName = pref.getSsortingng("prefSyncFrequency3", "Theme1"); if (themeName.equals("Africa")) { setTheme(R.style.AppTheme); } else if (themeName.equals("Colorful Beach")) { //Toast.makeText(this, "set theme", Toast.LENGTH_SHORT).show(); setTheme(R.style.beach); } else if (themeName.equals("Abstract")) { //Toast.makeText(this, "set theme", Toast.LENGTH_SHORT).show(); setTheme(R.style.abstract2); } else if (themeName.equals("Default")) { setTheme(R.style.defaulttheme); } 

Au lieu de

 getApplication().setTheme(R.style.BlackTheme); 

utilisation

 setTheme(R.style.BlackTheme); 

Mon code: dans la méthode onCreate ():

 super.onCreate(savedInstanceState); if(someExpression) { setTheme(R.style.OneTheme); } else { setTheme(R.style.AnotherTheme); } setContentView(R.layout.activity_some_layout); 

Quelque part (par exemple, en cliquant sur un bouton):

 YourActivity.this.recreate(); 

Vous devez recréer une activité, sinon – le changement ne se produira pas

Ce moyen fonctionne pour moi:

  @Override protected void onCreate(Bundle savedInstanceState) { setTheme(GApplication.getInstance().getTheme()); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } 

Ensuite, vous voulez changer un nouveau thème:

 GApplication.getInstance().setTheme(R.style.LightTheme); recreate(); 

Vous pouvez terminer l’Acivity et le recréer ensuite de cette manière, votre activité sera créée à nouveau et toutes les vues seront créées avec le nouveau thème.

Appelez SetContentView (Resource.Layout.Main) après setTheme ().

Cela n’a eu aucun effet pour moi:

 public void changeTheme(int newTheme) { setTheme(newTheme); recreate(); } 

Mais cela a fonctionné:

 int theme = R.style.default; protected void onCreate(Bundle savedInstanceState) { setTheme(this.theme); super.onCreate(savedInstanceState); } public void changeTheme(int newTheme) { this.theme = newTheme; recreate(); }