Android Holo themes with backwards compatibility
The Android platform provides a nice feature for app developers called themes. Themes allow developers to change the appearance of activities or the whole application easily. Developers can choose from themes like full-screen or no title bar, as well as ones that change the application from a dark to a light appearance. When Google introduced Android Honeycomb ( Version 3.X ) they also introduced a new theme family called Holo. This created a problem for app developers, if they target the new Holo theme in an application it will crash on older versions of Android. This may not seem like an issue but if we are using the old themes on new devices the application won’t look correct. For example:
Lets take a look at an example of the problem and then I’ll explain an easy fix. I have an existing activity that is using the no title bar theme:
<activity android:name="com.example.main" android:theme="@android:style/Theme.NoTitleBar" android:label="@string/app_name" />
I can’t simply change to the new holo theme as follows because it will break compatibilty with 1.X and 2.X phones:
<activity android:name="com.example.main" android:theme="@android:style/Theme.Holo.NoActionBar" android:label="@string/app_name" />
Luckily there is an easy solution to this problem! We just need to create our own themes that inherit from the standard android ones. We can then place the files into folders using resource qualifiers to make sure the correct theme gets applied on the correct device.
Your application will already have a values folder in its res directory, we can add a new one called values-v11. If you know about version qualifiers already feel free to skip ahead, otherwise I’ll quickly explain them here. We can qualify the items in a resource folder by adding qualifiers. These can be based on the android platform version, the screen density or many other options. For this example we need to apply different styles for devices running android versions 1.X and 2.X and devices running 3.X and 4.X. When using resource qualifiers you have to use the platform version. You can look them up here. The qualifiers work on a best-match system that is beyond the scope of this post but any version greater than 11 will use our new values-v11 folder. You should end up with something that looks like this:
You will need to start by creating a themes.xml file in the values folder and add the following text:
<resources xmlns:android="http://schemas.android.com/apk/res/android"> <style name="Theme.Default" parent="@android:style/Theme"></style> <style name="Theme.NoTitle" parent="@android:style/Theme.NoTitleBar"></style> <style name="Theme.FullScreen" parent="@android:style/Theme.NoTitleBar.Fullscreen"></style> </resources>
What we have done here is created three custom themes called Theme.Default, Theme.NoTitle and Theme.FullScreen and used the standard android themes as the parents. Now you can create a new themes.xml or copy this one into the values-v11 folder you created earlier. Edit it as follows:
<resources xmlns:android="http://schemas.android.com/apk/res/android"> <style name="Theme.Default" parent="@android:style/Theme.Holo"></style> <style name="Theme.NoTitle" parent="@android:style/Theme.Holo.NoActionBar"></style> <style name="Theme.FullScreen" parent="@android:style/Theme.Holo.NoActionBar.Fullscreen"></style> </resources>
Now we need to go back to our application manifest and update the activities theme to one of our new custom ones:
<activity android:name="com.example.main" android:theme="@style/Theme.NoTitle" android:label="@string/app_name" />
We’re all done. If the user is using an older version of android they will get the old no title bar theme and if they are using a new one they will see the new Holo theme. You may think this doesn’t really matter but if you set the theme to NoTitleBar and the user is running the app on a new device the will see dialogs from the older android versions. This can confuse users because its not what they are used to seeing, or leave them wondering why your app doesn’t work properly on their phone.
Feel free to post any questions below and make sure you use the right themes!!
I used this method to implement the Halo theme for recent version of Android but it does not find the necessary resources.
My app has minSdkTarget as 7
Hi,
I’m trying to implement this into my own app, but it won’t work. I have the minSdkVerision set to 10 (target 15), but even when I declare my theme in values-v11/themes.xml it still gives me “error: Error retrieving parent for item: No resource found that matches the given name ‘@android:style/Theme.Holo.Light’.”
values-v11/themes.xml looks like this:
I have updated the post since the example xml was missing the android namespace. Also you should clean the project if you have changed the target or min SDK version. Really sorry about the error
Hmm, my XML didn’t come through. Must be the greater than/less than.
<resources>
<style name=”MainStyle” parent=”@android:style/Theme.Holo.Light”>
</style>
</resources>
This should fix the issue
<resources xmlns:android=”http://schemas.android.com/apk/res/android” >
<style name=”MainStyle” parent=”@android:style/Theme.Holo.Light”>
</style>
</resources>
My problem was actually that I had my Project Build Target (in my Project Properties in Eclipse) set to 2.3.3, and I had to have it set to at least 4.0. I thought that if it was set to 4.0+ it wouldn’t run on 2.3.3, but I was wrong. As long as my minSdkVersion was set to 7 or so, it would run on 2.1+. Thanks anyway.
Hi,
I have made the changes as per this blog.
It is working fine for me.
But i encountered into a serious problem.
The buttons, imageviews in the layout becomes blured or larger now on higher devices.
Theme with no title bar is ok, but while applying the holo theme this issue comes.
What might be the reason for this.
just what i have been looking for