Brain Flush

Understanding Android Themes and Styles

Posted in Mobile Devices, Software Development & Programming by Matthias Käppler on March 15, 2009

I don’t know how many hours I’ve spent struggling with Android’s theme engine, trying to figure out — mostly by trial and error — how styles are applied and how to properly define them (let’s be honest: the documentation on styles in Android is a bit lacking). I thought it may be worth sharing what I’ve found out so far, in order to save my fellow Android developers from baldness due to ripped out hair (I sure lost some). This is a work in progress (so is Android), and some information may be inaccurate. If you find anything that you think is wrong or unclear, please let me know by dropping a line in the comments section. On another note, I assume that you have read the reference documentation on Android styles, if not, you should do that now.

What are Android styles?

A style in Android is a collection of attribute/value pairs applied to a view, an Activity or the entire application (which means, all Activities in your application). Styles for Activities are called themes, but do not get confused: they are syntactically equivalent to styles (because they are styles), they merely have a different scope. At this point I want to clarify something upfront: Themes or styles in Android have nothing to do with user styles known from applications such as, say, Firefox. Android users can not change the looks of Android applications by downloading themes from the Market or creating their own (yet). Android themes are of interest for developers only, think of them as syntactic sugar, a way of making your application’s view code more DRY.

How do I define custom styles?

Let’s look into a simple theme definition (stored in res/values/styles.xml):

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="MyTheme" parent="android:Theme.Light">
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowBackground">@color/translucent_blue</item>
        <item name="android:listViewStyle">@style/MyListView</item>
    </style>

    <style name="MyListView" parent="@android:style/Widget.ListView">
        <item name="android:listSelector">@drawable/list_selector</item>
    </style>
</resources>

First, we declare a new theme called MyTheme, which inherits from another theme called Theme.Light in the android namespace (specified by the ‘parent’ attribute). This means that all styles we do not explicitly specify in our custom theme will be merged down from the definition of android:Theme.Light (the curious among you may want to download the Android source code and go to frameworks/base/core/res/res/values to see how it is defined; all stock styles are defined in themes.xml and styles.xml in that folder).

In our theme definition, we also set some custom styles using the ‘item’ element. We set the windowNoTitle attribute to true, so all activities that use our theme won’t have a title bar. We also set the window background color to a custom color called ‘translucent_blue’; this is a resource reference (indicated by the @ symbol) to a color definition in values/colors.xml. We could also have passed a reference to a drawable here, or have provided a hex color value directly. Finally, we set the default style for ListView widgets to a custom style called MyListView. Its style definition follows the exact same structure as the MyTheme definition, just that this time it is not a theme, but simply a style that can be applied to ListView objects. It inherits from the default styles for ListView but replaces the default selector image with a custom drawable.

There are two important things to understand here. First, those two style definitions are completely independent of each other (well, apart from the fact that we reference MyListView in MyTheme of course). This means, that if I remove the reference to MyListView from MyTheme, I can still use that style by applying it manually to a ListView declaration in a layout file. Think of styles simply as a bunch of attributes and values you would have otherwise typed directly into your view definition, so instead of writing

<ListView android:listSelector="@drawable/list_selector" />

we write

<ListView style="@style/MyListView" />

or better yet, we let this style be applied automatically to all ListView widgets by setting it in a theme definition (as seen above). (Note the missing ‘android:’ namespace reference here; this is intentional, the ’style’ attribute is not defined in the ‘android’ namespace. You will get an error if you try to set a style using ‘android:style’, there is no such attribute.)

That way we never have to touch the ListView definition anymore; we can do all its styling from a single point, the style sheet. This helps in leaving the code for defining structure in your layouts, while leaving the code for defining appearance in your style sheets — a good example for separation of concerns. More importantly, your style definitions can be reused, which is particularly useful if styles are shared between several views.

The other important thing to understand is that styles do not have any type semantics. When we create a style called MyListView which inherits from Widget.ListView, then the intuition is that we are creating a style that is only supposed to apply to ListView objects. That’s not entirely correct though. There is no mechanism that will check whether we indeed apply that style to a ListView or even prevent us from applying it to an entirely different view type. It just so happens that Widget.ListView defines some attributes that only make sense when being applied to a ListView (such as listDivider), this doesn’t stop us, however, from creating a style that totally makes sense for any widget type (maybe because it only uses attributes defined in the View class, the parent class of all views). The bottom line is that you have to figure out yourself whether a style you define makes sense when you apply it to a view. Android will not do any sanity checks for you. In the worst case, the targeted view will expose odd behavior when being rendered, but more probably nothing will happen at all.

So what can I style, and from what can I inherit?

To get going with styles, it’s of course important to know two things:

  1. what’s there to be styled, and
  2. what styles are already there to inherit from

The easy answer is: Anything in android.R.styleable can be used inside a style body as a subject for styling (using the item tag), while anything in android.R.style can be used as parent styles to inherit from. So, to stick with the ListView example style, the android:listSelector style item can be found in android.R.styleable, while android:style/Widget.ListView is defined in android.R.style. Those two files are therefore what you want to turn your attention to first when defining custom styles. You should generally always inherit all default style items first, and then overwrite them one by one with your custom items.

That’s basically already it, a simple yet powerful style framework if used correctly!

Useful Tidbits

Text Appearance

Did you find yourself defining text appearance like font size or text color over and over again in your layouts? Don’t do that, use text appearances instead. Text appearances are styles, too, and Android already defines some for you which you can override (they are, of course, defined in R.style). This helps tremendously in keeping your view code DRY, and encourages you to get some structure into your different font styles used throughout your app by grouping them into styles you can reference and reuse. If, for example, you want to change the default text appearance in your app, simply define a custom text appearance in your stylesheet and set it as the default in your theme:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="MyTheme" parent="android:Theme.Light">
        <item name="android:textAppearance">@style/MyDefaultTextAppearance</item>
    </style>

    <style name="MyDefaultTextAppearance" parent="@android:style/TextAppearance">
        <item name="android:textSize">14dip</item>
        <item name="android:textColor">#333</item>
        <item name="android:textStyle">bold</item>
    </style>
</resources>

Make yourself familiar with all the text appearances Android already defines, and customize them for your application as you see fit.

Colors

Avoid setting color values directly in layouts or styles. Define them in a color resource file instead, and only use references to those color values from your layouts and styles. This helps in isolating them from the rest of your view code and makes your styles less brittle if you should decide to change a color afterwards. Another useful thing I usually do is define a transparent color called ‘transparent’ and assign it a value like #00000000. The first 8 bit, i.e. the first two hex digits, represent the alpha channel which is used to define opacity. A value of zero means zero opacity, or 100% transparency; the remaining color bits are therefore of no relevance, because they will be invisible, but to avoid confusion I just set them to zero, too. You can then turn the background of your views transparent by doing something like:

<style name="MyListView" parent="@android:style/Widget.ListView">
    <item name="android:background">@color/transparent</item>
</style>

That’s it for now. If I find out more about styles in Android, I’ll update this post accordingly. Feel free to contribute in the comments section, too.

Tagged with: , ,

15 Responses

Subscribe to comments with RSS.

  1. androidandme said, on March 16, 2009 at 2:14 am

    Wow great info. I’ve bookmarked your site.

  2. reynolds said, on March 19, 2009 at 10:36 am

    thanks! This topic really helped me understand styles and themes in its basic form :)

    Android’s SDK documentation is really giving me a tough time… geez

  3. justin said, on April 8, 2009 at 10:50 pm

    Great stuff. Thanks for the tips!

  4. jarvarm said, on April 18, 2009 at 1:48 pm

    It’s giving an error like – “No resource found that matches the given name (at “android:windowBackground” with value ‘@color/translucent_blue’

    • jetti said, on September 12, 2009 at 7:44 am

      hi,Jarvarm

      You asked the below question previously, i also get the same problem.so,if you get any solution to this please forward to jettimadhu@gmail.com.

      It’s giving an error like – “No resource found that matches the given name (at “android:windowBackground” with value ‘@color/translucent_blue’

      Thanx in advance

      • Matthias Käppler said, on September 13, 2009 at 6:58 pm

        that was just an example, there is no predefined color called “translucent_blue”.

        You have to create a file res/colors.xml and define all colors you use in that file. Or use the ones coming with android (@android:color/some_color).

  5. jarvarm said, on April 18, 2009 at 6:07 pm

    ok..jusst figured out. Need to define colors.xml
    Great tutorial. Thanks.

  6. joe said, on April 30, 2009 at 2:31 pm

    Thanks a lot, you saved me from balding a little more :)

  7. Charles said, on May 28, 2009 at 8:08 pm

    Kudos. Wish the android docs were this clear.

    I’m specifically try to create a dialog with a icon in the title bar (the menu more icon). I can use @Theme.Dialog to get almost all the way there, but not the icon. Is the icon something styleable, or do I need to go in muck about with new low level view definitions?

    • Matthias Käppler said, on May 28, 2009 at 9:05 pm

      Hey Charles,

      glad to hear that. As to your problem, I don’t believe title bar icons are set using styles; title bar features are typically changed by going through the Window class. Did you already try something like this:

      dialog.requestWindowFeature(Window.FEATURE_RIGHT_ICON);
      dialog.setFeatureDrawable(Window.FEATURE_RIGHT_ICON, iconDrawable);

      I didn’t actually test this code, but I believe it’s going in the right direction. Also, remember that custom window features must be requested before adding any content to the dialog (same for activities). Check the Dialog and Window class documentation for more info.

      Cheers,
      Matthias

  8. [...] guide is almost completely useless regarding themes, for example sample themes don’t work. This blog entry from Brainflush is much more informative, at least its examples work. The source that helped me the most was the [...]

  9. [...] Taken from brainflush blog [...]

  10. [...] project. started searching for other tutorials on the net on Android, like the one found on this link. There are tutorials found on the Android site but I’ve been trying to understand them for a [...]

  11. jetti said, on September 16, 2009 at 12:00 pm

    Hi Matthias Käppler,
    Thanx for your reply.Is there any alternative without help of colors.xml

  12. Stefan Klumpp said, on October 29, 2009 at 12:17 pm

    Thanks for writing this great post. All that information should go into the official Android documentation.


Leave a Reply