¿Cómo cambiar de tema (modo nocturno) sin reiniciar la actividad?

He hecho algunas aplicaciones que soportan múltiples temas, pero siempre tuve que reiniciar la aplicación cuando el usuario cambia de tema, porque setTheme() necesita ser llamado antes de setContentView() .

Yo estaba bien con él, hasta que descubrí esta aplicación. Puede cambiar perfectamente entre dos temas, y con transiciones / animaciones también!

Introduzca aquí la descripción de la imagen

Por favor, dame algunos consejos sobre cómo se implementó (y animaciones también). ¡Gracias!

3 Solutions collect form web for “¿Cómo cambiar de tema (modo nocturno) sin reiniciar la actividad?”

Respuesta @Alexander Hanssen básicamente ha respondido a esto … No sé por qué no fue aceptado … Tal vez debido a la finish () / startActivity (). He votado a favor y traté de comentar, pero no puedo …

De todos modos, yo haría exactamente lo que él describió en términos de estilos.

 <style name="AppThemeLight" parent="Theme.AppCompat.Light"> <!-- Customize your theme here. --> <item name="android:windowAnimationStyle">@style/WindowAnimationTransition</item> </style> <style name="AppThemeDark" parent="Theme.AppCompat"> <!-- Customize your theme here. --> <item name="android:windowAnimationStyle">@style/WindowAnimationTransition</item> </style> <!-- This will set the fade in animation on all your activities by default --> <style name="WindowAnimationTransition"> <item name="android:windowEnterAnimation">@android:anim/fade_in</item> <item name="android:windowExitAnimation">@android:anim/fade_out</item> </style> 

Pero en lugar de terminar / comenzar con una nueva intención:

 Intent intent = new Intent(this, <yourclass>.class); startActivity(intent); finish(); 

Yo lo haría:

 @Override protected void onCreate(Bundle savedInstanceState) { // MUST do this before super call or setContentView(...) // pick which theme DAY or NIGHT from settings setTheme(someSettings.get(PREFFERED_THEME) ? R.style.AppThemeLight : R.style.AppThemeDark); super.onCreate(savedInstanceState); } // Somewhere in your activity where the button switches the theme btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // decide which theme to use DAY or NIGHT and save it someSettings.save(PREFFERED_THEME, isDay()); Activity.this.recreate(); } }); 

El efecto es como se muestra en el video …

La transición / animación hace que el tema cambie sin problemas cuando se reinicia la actividad, lo que se puede hacer añadiendo los elementos "android: windowanimationStyle" a sus temas y luego haciendo referencia a un estilo donde se especifica cómo debe animarse la actividad al entrar y Salidas Tenga en cuenta que esto hace que la animación se aplique a todas las actividades con ese tema.

 <style name="AppThemeLight" parent="Theme.AppCompat.Light"> <!-- Customize your theme here. --> <item name="android:windowAnimationStyle">@style/WindowAnimationTransition</item> </style> <style name="AppThemeDark" parent="Theme.AppCompat"> <!-- Customize your theme here. --> <item name="android:windowAnimationStyle">@style/WindowAnimationTransition</item> </style> <!-- This will set the fade in animation on all your activities by default --> <style name="WindowAnimationTransition"> <item name="android:windowEnterAnimation">@android:anim/fade_in</item> <item name="android:windowExitAnimation">@android:anim/fade_out</item> </style> 

A continuación, cuando desee cambiar de tema, puede hacerlo al hacer clic en un botón:

 AppSettings settings = AppSettings.getInstance(this); settings.set(AppSettings.Key.USE_DARK_THEME, !settings.getBoolean(AppSettings.Key.USE_DARK_THEME)); Intent intent = new Intent(this, <yourclass>.class); startActivity(intent); finish(); 

A continuación, en el método onCreate , utilice el setTheme() para aplicar el tema que se establece actualmente en AppSettings como este:

 AppSettings settings = AppSettings.getInstance(this); setTheme(settings.getBoolean(AppSettings.Key.USE_DARK_THEME) ? R.style.AppThemeDark : R.style.AppThemeLight); super.onCreate(savedInstanceState); setContentView(<yourlayouthere>); 

Echa un vistazo a este tema para referencia: https://gist.github.com/alphamu/f2469c28e17b24114fe5

No hay nada que le impida llamar a setTheme() y luego a setContentView() nuevo. Sólo tendrá que reestructurar su aplicación un poco para que, si cambia el tema, necesita reinicializar cualquier variable de miembro que pueda tener que contenga referencias a objetos de View .

  • Heredando de Theme.AppCompat *
  • Leer atributos de tema más reciente en la plataforma anterior
  • Soporte ActionBar no mostrará el color correcto con API 21
  • ¿Cómo cambio el color de acento en las alertas de tema material de Android?
  • ¿Cómo puedo encontrar lo que android: attr / listChoiceIndicatorSingle apunta a?
  • Tema de botón incorrecto al cambiar el modo Día / Noche
  • Cambiar el color del tema en Runtime en Android
  • Obtener un valor de color attr basado en el tema de conjunto actual
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.