Change Activity's theme programmatically

In particular cases I need to remove dialog theme from my activity but it doesn't seem to be working. Here's an example

First activity:

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

Second activity:

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

Manifest excerpt:

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

When I run it's still dialog themed.

API10

Thanks.


Solution 1:

As docs say you have to call setTheme before any view output. It seems that super.onCreate() takes part in view processing.

So, to switch between themes dynamically you simply need to call setTheme before super.onCreate like this:

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

Solution 2:

user1462299's response works great, but if you include fragments, they will use the original activities theme. To apply the theme to all fragments as well you can override the getTheme() method of the Context instead:

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

You do not need to call setTheme() in the onCreate() Method anymore. You are overriding every request to get the current theme within this context this way.