You are reading an old article on an old site. It only still exists so the information is not lost. Comments and mosts links are hidden and disabled.

Themes across Android versions

This article unveils the secret of having your app's theme look consistent with the rest of the device's UI across all Android versions.

I don't often post pieces of code, but I thought this was an interesting enough subject to warrant a post. It's not really code, though.

If you've built a few apps, you've probably run into some theming issues. How do you get your app to have the standard OS look-and-feel across the different Android versions?

It's not difficult, but to have it look good on all current Android versions does require us to build the application for Android 4.0 (API level 14). Luckily, due to the introduction of the DeviceDefault theme, we will not have to upgrade the API level again in the future when a new theme comes out - it will now look good automatically.

We still have to cover the Honeycomb (Holo) and pre-Honeycomb (Black) cases, though. We do so by creating a new theme, and having it choose between device defaults by using API selectors. We will define three themes, the standard theme, a NoTitleBar(/NoActionBar) theme, and a Fullscreen theme.

If you modify your app in the way described here, standard components used by your activities will always look consistent with the rest of the device. Prior to Ice Cream Sandwich, OEMs usually skinned by overwriting the default skins, while in Ice Cream Sandwich and newer OEMs will modify the DeviceDefault skin. Note that on this API level you can still choose to use the Holo theme - and that Holo theme will actually look the way Google designed it, not OEM-specific.

Step 1: Changing Android API level

In Eclipse, right click on your project and go to Properties. Select the Android section, put a mark next to "Android 4.0" and click Apply.

If "Android 4.0" is not listed, make sure you install the needed SDK parts (Eclipse: Windows -> Android SDK Manager).

Now, open AndroidManifest.xml and make sure your <uses-sdk android:minSdkVersion="x" /> is still set to the minimum Android version you wish to support.

Step 2: Pre-Honeycomb theme (Black)

On Pre-Honeycomb Android devices, we'll use the Black theme, which is standard on most devices. We do so by creating a file called styles.xml in the res/values folder:

Code
#
1
<?xml version="1.0" encoding="utf-8"?>
2
<resources>
3
    <style 
4
        name="Theme.Chainfire"
5
        parent="android:Theme.Black">
6
    </style>
7
    <style 
8
        name="Theme.Chainfire.NoTitleBar"
9
        parent="android:Theme.Black.NoTitleBar">
10
    </style>
11
    <style 
12
        name="Theme.Chainfire.Fullscreen"
13
        parent="android:Theme.Black.NoTitleBar.Fullscreen">
14
    </style>
15
</resources>    

Step 3: Honeycomb theme (Holo)

On Honeycomb we want to be using the Holo theme available since Android 3.0 (API level 11). To do this, again we create a styles.xml file, but this time in the res/values-v11 folder:

Code
#
1
<?xml version="1.0" encoding="utf-8"?>
2
<resources>
3
    <style 
4
        name="Theme.Chainfire"
5
        parent="android:Theme.Holo">
6
    </style>
7
    <style 
8
        name="Theme.Chainfire.NoTitleBar"
9
        parent="android:Theme.Holo.NoActionBar">
10
    </style>
11
    <style 
12
        name="Theme.Chainfire.Fullscreen"
13
        parent="android:Theme.Holo.NoActionBar.Fullscreen">
14
    </style>
15
</resources>    

You might need to create that res/values-v11 folder. The v11 part is called an API selector. The styles.xml file present in this folder will override the styles.xml file present in the res/values folder if-and-only-if the API level of the device is 11 or higher.

Step 4: Post-Honeycomb theme (DeviceDefault)

On Ice Cream Sandwich and beyond, we will want to use the DeviceDefault theme, introduced in Android 4.0 (API level 14). This will ensure your app will look consistent with the rest of the device's user interface. We could keep using Holo, but prior to ICS OEMs modified the Holo theme to their liking, while on ICS and newer Holo will be Google standard. So if the OEM has changed the theme on ICS, and you are using Holo, your app will not look consistent with the rest of the device!

Again, we create a styles.xml file, this time for API level 14, so in the res/values-v14 folder:

Code
#
1
<?xml version="1.0" encoding="utf-8"?>
2
<resources>
3
    <style 
4
        name="Theme.Chainfire" 
5
        parent="android:Theme.DeviceDefault">
6
    </style>
7
    <style 
8
        name="Theme.Chainfire.NoTitleBar"
9
        parent="android:Theme.DeviceDefault.NoActionBar">
10
    </style>
11
    <style 
12
        name="Theme.Chainfire.Fullscreen"
13
        parent="android:Theme.DeviceDefault.NoActionBar.Fullscreen">
14
    </style>
15
</resources>

Step 5: Make your activities use the theme

This is quite simple. Open your AndroidManifest.xml file, it should look something like this:

Code
#
1
<?xml version="1.0" encoding="utf-8"?>
2
<manifest ...>
3
    <application ...>
4
        <activity ...
5
            android:theme="@style/Theme.Chainfire">
6
            ...
7
        </activity
8
    </application>
9
</manifest>

It is literally as easy as adding the android:theme attribute to each of your activities. Ofcourse, instead of Theme.Chainfire, you could also have used Theme.Chainfire.NoTitleBar or Theme.Chainfire.Fullscreen

Modifications

I have called these themes Theme.Chainfire.xxx, you can of course rename them to whatever you want to call them, but make sure you consistently change the name in all three styles.xml files.

I have also opted to use the dark theme variants. There are also light variants (Theme.Light, Theme.Holo.Light, Theme.DeviceDefault.Light) you can use instead, but be aware the dark variants are usually the device default.

If you are using ActionBarSherlock in your app, this simple solution does not work and needs further adaptation.

Recap

  • Set target API level to 14
  • Create res/values/styles.xml (Black)
  • Create res/values-v11/styles.xml (Holo)
  • Create res/values-v14/styles.xml (DeviceDefault)
  • Add android:theme to your activities in AndroidManifest.xml

Notes

After making these modifications, you will most likely have to Clean your project in Eclipse (Project -> Clean) for the changes to take effect. Often the build system will not recognize changes to xml files by itself.