Programowo zmieniaj motyw działania


121

W szczególnych przypadkach muszę usunąć motyw okna dialogowego z mojej aktywności, ale wydaje się, że nie działa. Oto przykład

Pierwsza czynność:

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

Druga czynność:

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

Manifest wyciąg:

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

Kiedy uruchamiam, nadal jest to okno dialogowe.

API10

Dzięki.

Odpowiedzi:


183

Jak mówią doktorzy , musisz zadzwonić setThemeprzed jakimkolwiek wyjściem widoku. Wydaje się, że super.onCreate()bierze udział w viewprzetwarzaniu.

Tak więc, aby dynamicznie przełączać się między motywami, wystarczy zadzwonić setThemewcześniej super.onCreate:

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

Działa dla mnie na MotoG (v1) ze stosem Androida 5.1. Jeśli to nie działa, udostępnij urządzenie + wersję Androida.
— lenrok258

Musiałem zdefiniować motyw zgodnie z opisem tutaj: stackoverflow.com/a/44236460/3211335 A następnie ustawić go zgodnie z opisem w tej odpowiedzi. Działa świetnie.
— LaloLoop

Czy w ogóle możemy ustawić motyw tylko raz ... zamiast ustawiać motyw na stronę
— gayan1991

Używam wspólnych preferencji, aby zapisać motyw, ale po ponownym uruchomieniu aplikacji przez chwilę pojawia się pierwszy motyw, a następnie pojawia się drugi motyw!
— Mohammad Afrashteh

1
@ gayan1991 Możesz użyć innego działania, aby zdefiniować swój motyw i rozszerzyć wszystkie inne działania, np .: pastebin.com/r93qrRDG edit: użyj pastebin, aby uzyskać lepsze formatowanie
— SocialSupaCrew

46

Odpowiedź użytkownika1462299 działa świetnie, ale jeśli dołączysz fragmenty , użyją oryginalnego motywu działań. Aby zastosować motyw również do wszystkich fragmentów, możesz zamiast tego nadpisać metodę getTheme () 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;
}

Nie ma już potrzeby wywoływania setTheme () w metodzie onCreate (). W ten sposób nadpisujesz każde żądanie uzyskania aktualnego motywu w tym kontekście.


2
@ ktokolwiek zlekceważył: czy możesz wyjaśnić, co ci się nie podoba w mojej odpowiedzi?
— Björn Kechel

Czy metoda getTheme () powinna zostać zastąpiona w działaniu, czy w odpowiednich fragmentach? Zaimplementowałem to w działaniu, ale fragmenty nadal używają oryginalnego motywu działania.
— saltandpepper

@saltandpepper Zastępowanie go w działaniu wystarczy. Upewnij się, że kod fragmentu i układ nie zmieniają go ponownie.
— Björn Kechel

To nie zadziałało, ale odpowiedź podana na stackoverflow.com/a/15496425/494179 tak.
— sól i pieprz

2
Dobry punkt użytkownika1269737, więc powinieneś upewnić się, że nie ma ciężkich obliczeń. Zwrócenie stylu w prostym przypadku warunku nie wpłynie na wydajność.
— Björn Kechel

12

Wiem, że jestem późno, ale chciałbym, aby umieścić tu rozwiązanie:
Sprawdź pełny kod źródłowy tutaj .
To jest kod, którego użyłem podczas zmiany motywu za pomocą preferencji.

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

}

Pamiętaj, że musisz umieścić kod przed setcontentview ..

SZCZĘŚLIWEGO KODOWANIA!


czemu? odpowiedź jest poprawna ?!
— dondondon,

Używam wspólnych preferencji, aby zapisać motyw, ale po ponownym uruchomieniu aplikacji przez chwilę pojawia się pierwszy motyw, a następnie pojawia się drugi motyw!
— Mohammad Afrashteh

0

Ten działa dobrze dla mnie:

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

Stosowanie:

  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)
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.