De hecho, tengo esta característica en mi aplicación y, además, les permito a los usuarios cambiar el tema en tiempo de ejecución. Como la lectura de un valor de las preferencias lleva algo de tiempo, obtengo una identificación de tema a través de una función accesible globalmente que contiene el valor en caché.
Como ya se señaló, cree algunos temas de Android, usando this guide. Tendrá al menos dos elementos <style>
en su archivo styles.xml
. Por ejemplo:
<style name="Theme.App.Light" parent="@style/Theme.Light">...</style>
<style name="Theme.App.Dark" parent="@style/Theme">...</style>
Ahora, usted tiene que solicitar uno de estos estilos para sus actividades. Estoy haciendo esto en el método de activida onCreate
, antes que cualquier otra llamada:
setTheme(MyApplication.getThemeId());
getThemeId
es un método que devuelve caché ID Tema:
public static int getThemeId()
{
return themeId;
}
Este campo está siendo actualizado por otro método:
public static void reloadTheme()
{
themeSetting = PreferenceManager.getDefaultSharedPreferences(context).getString("defaultTheme", "0");
if(themeSetting.equals("0"))
themeId = R.style.Theme_Light;
else
themeId = R.style.Theme_Dark;
}
que se llama cada vez que se cambian las preferencias (y, al inicio del curso). Estos dos métodos residen en la clase MyApplication
, que se extiende en Application
. El oyente de cambio de preferencia se describe al final de esta publicación y reside en la clase de actividad principal.
Lo último y bastante importante: el tema se aplica cuando comienza una actividad. Asumiendo, puede cambiar un tema solo en la pantalla de preferencias y que solo hay una manera de llegar allí, es decir, de una sola actividad (principal), esta actividad no se reiniciará cuando salga de la pantalla de preferencias: el tema anterior seguirá siendo usado. Aquí está la solución para que (reinicia su actividad principal):
@Override
protected void onResume() {
super.onResume();
if(schduledRestart)
{
schduledRestart = false;
Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName());
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
}
scheduledRestart
es una variable booleana, inicialmente establecido en false. Se establece en true cuando el tema se cambia por este oyente, que también actualiza ID tema en caché se mencionó antes:
private class themeListener implements OnSharedPreferenceChangeListener{
@Override
public void onSharedPreferenceChanged(SharedPreferences spref, String key) {
if(key.equals("defaultTheme") && !spref.getString(key, "0").equals(MyApplication.getThemeSetting()))
{
MyApplication.reloadTheme();
schduledRestart = true;
}
}
sp = PreferenceManager.getDefaultSharedPreferences(this);
listener = new themeListener();
sp.registerOnSharedPreferenceChangeListener(listener);
Recuerde que debe mantener una referencia al objeto detector, de lo contrario será basura, recolectados (y dejará de trabajo)
¡Excelente respuesta, muchas gracias! –
Pensé que podría resolver sin extender la Aplicación, pero el problema es que 'getApplicationInfo(). Theme' no se actualiza si hago una' getApplication(). SetTheme (myThemeId) '... así que sí, tu camino es correcto . – vault
Parece que hay un método más simple para reiniciar una actividad actualmente: 'recreate' (https://developer.android.com/reference/android/app/Activity.html#recreate%28%29). – BlueMonkMN