Changer le thème de l'activité par programmation

121

Dans des cas particuliers, je dois supprimer le thème de dialogue de mon activité, mais cela ne semble pas fonctionner. Voici un exemple

Première activité:

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

Deuxième activité:

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

Extrait du manifeste:

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

Quand je cours, c'est toujours le thème du dialogue.

API10

Merci.

user1462299
la source

Réponses:

183

Comme le disent les documents, vous devez appeler setThemeavant toute sortie de vue. Il semble que cela super.onCreate()participe au viewtraitement.

Donc, pour basculer dynamiquement entre les thèmes, il vous suffit d'appeler setThemeavant super.onCreatecomme ceci:

public void onCreate(Bundle savedInstanceState) {
    setTheme(android.R.style.Theme);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);
}
user1462299
la source
Fonctionne pour moi sur MotoG (v1) avec pile Android 5.1. Si cela ne fonctionne pas pour vous, veuillez partager l'appareil + la version Android.
lenrok258
J'ai dû définir un thème comme décrit ici: stackoverflow.com/a/44236460/3211335 Et puis le définir comme décrit par cette réponse. Cela fonctionne très bien.
LaloLoop
Y a-t-il de toute façon que nous pourrions définir le thème une seule fois ... au lieu de définir le thème par page
gayan1991
J'utilise la préférence partagée pour enregistrer le thème mais lors du redémarrage de l'application, pendant un moment le premier thème apparaît puis le deuxième thème affiché!
Mohammad Afrashteh
1
@ gayan1991 Vous pouvez utiliser une autre activité pour définir votre thème et faire en sorte que toutes vos autres activités étendent celle-ci ex: pastebin.com/r93qrRDG edit: utilisez pastebin pour avoir un meilleur formatage
SocialSupaCrew
46

La réponse de user1462299 fonctionne très bien, mais si vous incluez des fragments , ils utiliseront le thème des activités d'origine. Pour appliquer également le thème à tous les fragments, vous pouvez remplacer la méthode getTheme () du Context à la place:

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

Vous n'avez plus besoin d'appeler setTheme () dans la méthode onCreate (). Vous remplacez chaque demande pour obtenir le thème actuel dans ce contexte de cette façon.

Björn Kechel
la source
2
@ celui qui a voté contre: voulez-vous expliquer ce que vous n'aimez pas dans ma réponse?
Björn Kechel
GetTheme () doit-il être remplacé dans l'activité ou dans les fragments respectifs? J'ai implémenté cela dans l'activité, mais les fragments utilisent toujours le thème d'activité d'origine.
saltandpepper
@saltandpepper Le remplacer dans l'activité suffit. Assurez-vous que votre code de fragment et votre mise en page ne les modifient plus.
Björn Kechel
Cela n'a pas fonctionné pour moi, mais la réponse fournie dans stackoverflow.com/a/15496425/494179 l'a fait.
saltandpepper
2
Bon point user1269737 donc vous devez vous assurer qu'il n'y a pas de calcul lourd. Le simple renvoi d'un style dans un cas de condition simple n'affectera pas les performances.
Björn Kechel
12

Je sais que je suis en retard mais je voudrais poster une solution ici:
Vérifiez le code source complet ici .
C'est le code que j'ai utilisé lors du changement de thème à l'aide des préférences.

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

}

Veuillez noter que vous devez mettre le code avant setcontentview ..

CODAGE HEUREUX!

Dunondon
la source
Pourquoi? la réponse est corect?!
lundi
J'utilise la préférence partagée pour enregistrer le thème mais lors du redémarrage de l'application, pendant un moment le premier thème apparaît puis le deuxième thème affiché!
Mohammad Afrashteh
0

Celui-ci fonctionne bien pour moi:

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

Usage:

  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
la source