Modifica il tema dell'attività a livello di programmazione


121

In casi particolari ho bisogno di rimuovere il tema della finestra di dialogo dalla mia attività ma sembra che non funzioni. Ecco un esempio

Prima attività:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    startActivity(new Intent(MainActivity.this, SecondActivity.class));
}

Seconda attività:

public void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setTheme(android.R.style.Theme);
    setContentView(R.layout.activity_second);
}

Estratto del manifesto:

 <activity android:name="SecondActivity" android:theme="@android:style/Theme.Dialog"></activity>

Quando corro è ancora a tema dialoghi.

API10

Grazie.

Risposte:


183

Come dicono i documenti, devi chiamare setThemeprima di qualsiasi output di visualizzazione. Sembra che super.onCreate()prenda parte viewall'elaborazione.

Quindi, per passare da un tema all'altro in modo dinamico, devi semplicemente chiamare setThemeprima in super.onCreatequesto modo:

public void onCreate(Bundle savedInstanceState) {
    setTheme(android.R.style.Theme);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);
}

Funziona per me su MotoG (v1) con stack Android 5.1. Se non funziona per te, condividi il dispositivo + la versione Android.
— lenrok258

Ho dovuto definire un tema come descritto qui: stackoverflow.com/a/44236460/3211335 E poi impostarlo come descritto da questa risposta. Funziona benissimo.
— LaloLoop

Possiamo comunque impostare il tema solo una volta ... invece di impostare il tema per pagina
— gayan1991

Uso la preferenza condivisa per salvare il tema, ma quando riavvio l'app, per un momento appare il primo tema, quindi viene mostrato il secondo tema!
— Mohammad Afrashteh

1
@ gayan1991 Puoi usare un'altra attività per definire il tuo tema e fare in modo che tutte le tue altre attività estendano questo ex: pastebin.com/r93qrRDG modifica: usa pastebin per avere una formattazione migliore
— SocialSupaCrew

46

La risposta di user1462299 funziona alla grande, ma se includi frammenti , useranno il tema delle attività originali. Per applicare il tema anche a tutti i frammenti, puoi invece sostituire il metodo getTheme () del Context:

@Override
public Resources.Theme getTheme() {
    Resources.Theme theme = super.getTheme();
    if(useAlternativeTheme){
        theme.applyStyle(R.style.AlternativeTheme, true);
    }
    // you could also use a switch if you have many themes that could apply
    return theme;
}

Non è più necessario chiamare setTheme () nel metodo onCreate (). Stai annullando ogni richiesta per ottenere il tema corrente in questo contesto in questo modo.


2
@ chi ha votato negativamente: ti interessa spiegare cosa non ti piace della mia risposta?
— Björn Kechel

GetTheme () dovrebbe essere sovrascritto nell'attività o nei rispettivi frammenti? L'ho implementato nell'attività, ma i frammenti utilizzano ancora il tema dell'attività originale.
— saltandpepper

@saltandpepper È sufficiente sovrascriverlo nell'attività. Assicurati che il codice e il layout del frammento non lo cambino di nuovo.
— Björn Kechel

Questo non ha funzionato per me, ma la risposta fornita in stackoverflow.com/a/15496425/494179 sì .
— saltandpepper

2
Buon punto user1269737 quindi dovresti assicurarti che non ci siano calcoli pesanti. La semplice restituzione di uno stile all'interno di una semplice condizione non influirà sulle prestazioni.
— Björn Kechel

12

So di essere in ritardo ma vorrei pubblicare una soluzione qui:
controlla il codice sorgente completo qui .
Questo è il codice che ho usato quando ho cambiato tema usando le preferenze.

SharedPreferences pref = PreferenceManager
        .getDefaultSharedPreferences(this);
String themeName = pref.getString("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);

}

Tieni presente che devi inserire il codice prima di setcontentview ..

CODIFICA FELICE!


perché? la risposta è corretta ?!
— dondondon

Uso la preferenza condivisa per salvare il tema, ma quando riavvio l'app, per un momento appare il primo tema, quindi viene mostrato il secondo tema!
— Mohammad Afrashteh

0

Questo funziona bene per me:

theme.applyStyle(R.style.AppTheme, true)

Uso:

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    //The call goes right after super.onCreate() and before setContentView()
    theme.applyStyle(R.style.AppTheme, true)
    setContentView(layoutId)
    onViewCreated(savedInstanceState)
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.