Ändern Sie das Thema der Aktivität programmgesteuert

121

In bestimmten Fällen muss ich das Dialogthema aus meiner Aktivität entfernen, aber es scheint nicht zu funktionieren. Hier ist ein Beispiel

Erste Aktivität:

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

Zweite Aktivität:

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

Manifestierter Auszug:

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

Wenn ich starte, ist es immer noch ein Dialog-Thema.

API10

Vielen Dank.

user1462299
quelle

Antworten:

182

Wie die Dokumente sagen, müssen Sie setThemevor jeder Ansichtsausgabe aufrufen . Es scheint, dass super.onCreate()an der viewVerarbeitung beteiligt ist.

Um dynamisch zwischen Themen zu wechseln, müssen Sie einfach setThemevorher super.onCreatewie folgt aufrufen :

public void onCreate(Bundle savedInstanceState) {
    setTheme(android.R.style.Theme);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);
}
user1462299
quelle
Funktioniert für mich auf MotoG (v1) mit Stack Android 5.1. Wenn es für Sie nicht funktioniert, teilen Sie bitte Gerät + Android-Version.
Lenrok258
Ich musste ein Thema wie hier beschrieben definieren: stackoverflow.com/a/44236460/3211335 Und es dann wie in dieser Antwort beschrieben einstellen. Es funktioniert großartig.
LaloLoop
Gibt es sowieso wir könnten Thema nur einmal setzen ... anstatt Thema pro Seite zu setzen
gayan1991
Ich verwende die gemeinsame Einstellung, um das Thema zu speichern, aber beim Neustart der App erscheint für einen Moment das erste Thema und dann das zweite gezeigte Thema!
Mohammad Afrashteh
1
@ gayan1991 Sie können eine andere Aktivität verwenden, um Ihr Thema zu definieren und alle anderen Aktivitäten zu erweitern. Beispiel: pastebin.com/r93qrRDG Bearbeiten: Verwenden Sie Pastebin, um eine bessere Formatierung zu
erzielen
46

Die Antwort von user1462299 funktioniert hervorragend, aber wenn Sie Fragmente einfügen , wird das ursprüngliche Aktivitätsthema verwendet. Um das Thema auch auf alle Fragmente anzuwenden, können Sie stattdessen die Methode getTheme () des Kontexts überschreiben :

@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;
}

Sie müssen setTheme () in der onCreate () -Methode nicht mehr aufrufen. Auf diese Weise überschreiben Sie jede Anforderung, das aktuelle Thema in diesem Kontext abzurufen.

Björn Kechel
quelle
2
@ wer auch immer herabgestimmt hat: Möchtest du erklären, was dir an meiner Antwort nicht gefällt?
Björn Kechel
Sollte getTheme () in der Aktivität oder in den jeweiligen Fragmenten überschrieben werden? Ich habe dies in der Aktivität implementiert, aber die Fragmente verwenden immer noch das ursprüngliche Aktivitätsthema.
Saltandpepper
@saltandpepper Es reicht aus, es in der Aktivität zu überschreiben. Stellen Sie sicher, dass Ihr Fragmentcode und Ihr Layout ihn nicht erneut ändern.
Björn Kechel
Dies hat bei mir nicht funktioniert, aber die Antwort unter stackoverflow.com/a/15496425/494179 hat funktioniert.
Saltandpepper
2
Guter Punkt user1269737, also sollten Sie sicherstellen, dass es keine schwere Berechnung gibt. Die einfache Rückgabe eines Stils in einem einfachen Fall hat keinen Einfluss auf die Leistung.
Björn Kechel
12

Ich weiß, dass ich zu spät komme, aber ich möchte hier eine Lösung veröffentlichen:
Überprüfen Sie den vollständigen Quellcode hier .
Dies ist der Code, den ich beim Ändern des Themas mithilfe von Einstellungen verwendet habe.

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);

}

Bitte beachten Sie, dass Sie den Code vor setcontentview eingeben müssen.

GLÜCKLICHE CODIERUNG!

Dondondon
quelle
Warum? Die Antwort ist richtig?!
Dondondon
Ich verwende die gemeinsame Einstellung, um das Thema zu speichern, aber beim Neustart der App erscheint für einen Moment das erste Thema und dann das zweite gezeigte Thema!
Mohammad Afrashteh
0

Dieser funktioniert gut für mich:

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

Verwendung:

  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)
}
Tamim Attafi
quelle