Como alterar o tema actual à hora de execução no Android [duplicate]

Esta pergunta já tem uma resposta:

criei uma Preferenceactividade que permite ao utilizador escolher o tema que quer aplicar a toda a aplicação.

Quando o utilizador selecciona um tema, este código é executado:

if (...) {
    getApplication().setTheme(R.style.BlackTheme);
} else {
    getApplication().setTheme(R.style.LightTheme);
}
Mas, apesar de eu ter assinalado com o depurador que o código está a ser executado, não consigo ver qualquer alteração na interface do utilizador.

Os temas são definidos em res/values/styles.xml, e o Eclipse não mostra nenhum erro.

<resources>
    <style name="LightTheme" parent="@android:style/Theme.Light">
    </style>

    <style name="BlackTheme" parent="@android:style/Theme.Black">
    </style>    
</resources>
Alguma ideia do que pode estar a acontecer e como resolvê-lo? Devo ligar para algum ponto especial do Código? A minha aplicação consiste em várias actividades, se isso ajudar.

Author: Peter O., 2010-03-20

13 answers

Também gostaria de ver o método em que definiste uma vez para todas as tuas actividades. Mas, tanto quanto sei, você tem que se estabelecer em cada atividade antes de mostrar quaisquer opiniões.

Para verificação de referência, isto:

Http://www.anddev.org/applying_a_theme_to_your_application-t817.html

Editar (copiado desse fórum):

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Call setTheme before creation of any(!) View.
     setTheme(android.R.style.Theme_Dark);

    // ...
    setContentView(R.layout.main);
}
 73
Author: Pentium10, 2016-10-01 09:39:56

Se quiser mudar o tema de uma actividade já existente, ligue recreate() Depois setTheme().

Nota: Não ligue para recriar se mudar de tema em onCreate(), para evitar o ciclo infinito.
 48
Author: TPReal, 2017-02-28 10:46:43

recreate() (Como mencionado por TPReal ) só irá reiniciar a actividade actual, mas as actividades anteriores ainda estarão na pilha de trás e o tema não será aplicado a elas.

Então, outra solução para este problema é recriar a pilha de tarefas completamente, assim:

    TaskStackBuilder.create(getActivity())
            .addNextIntent(new Intent(getActivity(), MainActivity.class))
            .addNextIntent(getActivity().getIntent())
            .startActivities();

Editar:

Basta colocar o código acima depois de realizar a mudança de tema na UI ou em qualquer outro lugar. Todas as suas atividades devem ter o método setTheme() chamado antes de onCreate(), provavelmente em alguns actividade parental. É também uma abordagem normal armazenar o tema escolhido em SharedPreferences, lê-o e depois define usando o método setTheme().

 17
Author: Yuriy Yunikov, 2017-05-23 11:47:06
Tenho o mesmo problema, mas encontrei a solução.
public class EditTextSmartPhoneActivity extends Activity implements DialogInterface.OnClickListener
{
    public final static int CREATE_DIALOG  = -1;
    public final static int THEME_HOLO_LIGHT  = 0;
    public final static int THEME_BLACK  = 1;

    int position;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        position = getIntent().getIntExtra("position", -1);

        switch(position)
        {
        case CREATE_DIALOG:
            createDialog();
            break;
        case THEME_HOLO_LIGHT:
            setTheme(android.R.style.Theme_Holo_Light);
            break;
        case THEME_BLACK:
            setTheme(android.R.style.Theme_Black);
            break;
        default:
        }

        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

    }

    private void createDialog()
    {
        /** Options for user to select*/
        String choose[] = {"Theme_Holo_Light","Theme_Black"};

        AlertDialog.Builder b = new AlertDialog.Builder(this);

        /** Setting a title for the window */
        b.setTitle("Choose your Application Theme");

        /** Setting items to the alert dialog */
        b.setSingleChoiceItems(choose, 0, null);

        /** Setting a positive button and its listener */
        b.setPositiveButton("OK",this);

        /** Setting a positive button and its listener */
        b.setNegativeButton("Cancel", null);

        /** Creating the alert dialog window using the builder class */
        AlertDialog d = b.create();

        /** show dialog*/
        d.show();
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
        // TODO Auto-generated method stub
        AlertDialog alert = (AlertDialog)dialog;
        int position = alert.getListView().getCheckedItemPosition();

        finish();
        Intent intent = new Intent(this, EditTextSmartPhoneActivity.class);
        intent.putExtra("position", position);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
    }
}
 15
Author: Unknown, 2013-01-01 11:51:09
Tive um problema semelhante e resolvi-o desta forma..
@Override
public void onCreate(Bundle savedInstanceState) {

    if (getIntent().hasExtra("bundle") && savedInstanceState==null){
        savedInstanceState = getIntent().getExtras().getBundle("bundle");
    }

    //add code for theme

    switch(theme)
    {
    case LIGHT:
        setTheme(R.style.LightTheme);
        break;
    case BLACK:
        setTheme(R.style.BlackTheme);
        break;

    default:
    }
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //code

}

Este código é para recriar o pacote de poupança de actividade e mudar o tema. Você tem que escrever o seu próprio onSaveInstanceState (Bundle outState); a partir da API-11 Você pode usar o método recriar () em vez de

Bundle temp_bundle = new Bundle();
onSaveInstanceState(temp_bundle);
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("bundle", temp_bundle);
startActivity(intent);
finish();
 9
Author: Francesco Ditrani, 2013-06-12 22:21:57
Temos de definir o tema antes de chamar 'Óptimo.oncreato()' e 'setContentView()' método. Olha para isto. Relação para aplicar um novo tema a toda a aplicação no tempo de execução.
 9
Author: Lalit Sharma, 2015-09-08 13:51:42
Isto é o que eu criei para o design do Material. Que te ajude.

Procura por multiplica a concepção material

 2
Author: Pratik Butani, 2015-08-20 07:24:41
Eu sei que estou atrasado, mas gostaria de colocar uma solução aqui.: Verifique o código-fonte completo aqui . Este é o código que usei ao mudar de tema usando preferências..
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);
}
 2
Author: dondondon, 2015-10-24 16:35:48

Em vez de

getApplication().setTheme(R.style.BlackTheme);

Utilizar

setTheme(R.style.BlackTheme);

O meu código: método do oncreato ():

super.onCreate(savedInstanceState);

if(someExpression) {
    setTheme(R.style.OneTheme);
} else {
    setTheme(R.style.AnotherTheme);
}

setContentView(R.layout.activity_some_layout);

Algures (por exemplo, num botão, carregue):

YourActivity.this.recreate();

Você tem que recriar a atividade, caso contrário-a mudança não vai acontecer

 2
Author: Vitaly Zinchenko, 2015-12-04 11:43:44
Por aqui, funciona para mim.
  @Override
protected void onCreate(Bundle savedInstanceState) {
    setTheme(GApplication.getInstance().getTheme());
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);
}

Então você quer mudar um novo tema:

GApplication.getInstance().setTheme(R.style.LightTheme);
recreate();
 2
Author: duongnx, 2016-11-15 10:07:54

Você pode terminar a actividade e recriá-la depois desta forma, a sua actividade será criada de novo e todas as vistas serão criadas com o novo tema.

 1
Author: Sumit Dhaniya, 2012-07-18 09:34:16

Call SetContentView (Resource.Esquema.Main) after setTheme().

 0
Author: MohammadReza Moradi, 2016-06-07 04:52:56

Isto não teve efeito para mim:

public void changeTheme(int newTheme) {
    setTheme(newTheme);
    recreate();
}

Mas isto funcionou:

int theme = R.style.default;

protected void onCreate(Bundle savedInstanceState) {
    setTheme(this.theme);
    super.onCreate(savedInstanceState);
}

public void changeTheme(int newTheme) {
    this.theme = newTheme;
    recreate();
}
 0
Author: arlomedia, 2016-07-27 07:36:27