Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set a theme to whole application in code, but not in the Manifest?

Tags:

android

themes

I know how to set theme to whole application in manifest,but how to set theme to whole application programmatically ? I am trying this: getApplicationContext.setTheme(R.style.mytheme), but it doesn't work.

I think the getApplicationContext is the Application's Context, which can set whole application theme.

like image 752
Judy Avatar asked Apr 01 '11 05:04

Judy


2 Answers

I spent a lot of time getting this to work and now my app has selectable Light and Dark themes which can even be selected dynamically coming immediately into play including Prefs. Below is the resource I use with some other ideas commented out which I played with at some starge.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!--The base theme ensures nothing is shown until the first activity. All activities and fragmenst must-->
    <!--set a them in onCreate or in AndroidManifext or they wil crash because of no title.-->
    <!--Using Theme.Holo.NoActionBar suppresses the ActionBar initially so Icon doesn't show until new theme is set.-->
    <style name="MyAppThemeInitial" parent="@android:style/Theme.Holo">
        <!--<item name="android:windowBackground">@color/initial_background_grey</item>-->
        <!--<item name="android:actionBarStyle">@style/MyActionBar</item>-->
        <item name="android:windowDisablePreview">true</item>

    </style>
    <style name="MyAppThemeDark" parent="@android:style/Theme.Holo">
        <item name="android:windowBackground">@color/black</item>
    </style>
    <style name="MyAppThemeLight" parent="android:Theme.Holo.Light">
    <item name="android:windowBackground">@color/white</item>
    </style>


<!--&lt;!&ndash;This is so that only the icon is showing in the intial theme&ndash;&gt;-->
    <!--&lt;!&ndash; ActionBar styles &ndash;&gt;-->
    <!--<style name="MyActionBar" parent="@android:style/Widget.Holo.ActionBar">-->
        <!--<item name="android:background">@android:color/transparent</item>-->
        <!--<item name="android:titleTextStyle">@style/MyActionBarTextAppearance</item>-->
    <!--</style>-->

    <!--<style name="MyActionBarTextAppearance">-->
        <!--<item name="android:textColor">@android:color/transparent</item>-->
    <!--</style>-->

</resources> 

The key item here is

<item name="android:windowDisablePreview">true</item>

and that took me a while to realize. My app does some heavy lifting while starting so it was important to not have the mandatory Manifest theme showing before the one I set in onCreate.

To be able to restart the app dynamically I check if this was how the app was started/restarted like this.

SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
boolean useThemeLight = sp.getBoolean("useThemeLight", false);
//Since this Activity can also be started by the Theme Toggle in the Action bar we need to see if
//there is a TOGGLE_THEME extra which only it uses
Intent curIntent = this.getIntent();
if (curIntent.getExtras() != null && curIntent.getExtras().containsKey(TOGGLE_THEME)) {
    if(curIntent.getStringExtra(TOGGLE_THEME).equals("Dark")){
        this.setTheme(R.style.MyAppThemeDark);
        CurrentTheme = "Dark";
    }else{
        this.setTheme(R.style.MyAppThemeLight);
        CurrentTheme = "Light";
    }
    activityThemeToggleActive = true;
} else {
    if (useThemeLight) {
        this.setTheme(R.style.MyAppThemeLight);
        CurrentTheme = "Light";
    } else {
        this.setTheme(R.style.MyAppThemeDark);
        CurrentTheme = "Dark";
    }
}

In Preferences I do this.

SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
boolean useThemeLight = sp.getBoolean("useThemeLight", false);
if (useThemeLight) {
    this.setTheme(R.style.MyAppThemeLight);
} else {
    this.setTheme(R.style.MyAppThemeDark);
}

Hope this gets you started. Regards, John.

like image 66
jcddcjjcd Avatar answered Oct 19 '22 05:10

jcddcjjcd


Call setTheme before super.onCreate() similar to below code

  public void onCreate(Bundle icicle) {
           if(Utility.isThemed)
             setTheme(R.style.Mytheme);
           super.onCreate(icicle);
    .....
    .....
}
like image 20
100rabh Avatar answered Oct 19 '22 07:10

100rabh