If you have read the other articles in this series, then you should be getting quite familiar with applying styles to layouts and widgets, and we can get some pretty good results by combining the techniques that we’ve learned so far. While it is certainly possible to apply a, for example, button style to every occurrence of a button widget within our app, there is actually an easier way: Themes. Themes are strangely under-documented on the Android Developer website, but they are an extremely useful tool for applying a UI design consistently across an app, and even applying a consistent UI design across multiple apps.
The best resource for understanding how themes work is the Android Open Source Project (AOSP). AOSP is the Android source code that Google have released to the Open Source community and is a superb repository for example code and best practice, albeit as standalone code without much explanation. The biggest problem with AOSP is it is huge, and it can be a daunting prospect to actually find what you’re looking for. To begin to understand themes, the best place to look is here which is the core theme for the entire platform.
To offer a little more explanation, the Android source can be browsed online at http://android.git.kernel.org (or you can checkout a full copy from the git repository by following the instructions here). There are a large number of top-level components, some of which represent individual components and native apps, some are hardware specific, and others are vendor specific. What we are interested in is the core styling of Android, and this is located within the platform/frameworks/base package. Within this framework are a number of sub-projects which can be viewed by clicking the “tree” link just below the “Summary” line. The sub-project that we’re interested in is the one named “core”, and the structure of this project is similar to a standard Android project. The only oddity is that if you look inside the “res” folder, there is a “res” and and “assets” folder, so we actually need to go in to res/res/values/theme.xml to get to the file that is of interest to us.
Now that we’ve got to the theme definition, let’s examine it to understand how it works. In essence, a theme is no different to a style. Syntactically it is the same. The real difference is that Android defines some custom attribute names which allow us to set values which get assigned to different widget types automatically. For example, “buttonStyle” defines which style will be assigned to all buttons, and “textAppearanceButton” defines a style which will be applied to the text within all buttons. So, if we have already defined a new button style, then we can apply it to all buttons within our app by creating a new theme file in res/values/themes.xml:
1 2 3 4 5 6 7
<?xml version="1.0" encoding="utf-8"?> <resources> <style name="MyTheme" parent="@android:style/Theme"> <item name="android:buttonStyle">@style/MyButtonStyle</item> <item name="android:textAppearanceButton">@style/MyButtonText</item> </style> </resources>
it is worth pointing out that we must include the prefix “android:” to the names defined by Android. This is because they are defined within the Android package, and if we do not include this in our theme, Android will try to resolve definitions from our own package (which do not exist) instead of the ones defined by Android.
Now all we need to do is to apply this theme to the application in the Manifest:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.stylingandroid.themes" android:versionCode="1" android:versionName="1"> <uses-sdk android:targetSdkVersion="10"/> <application android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@style/MyTheme"> . . . </application> . . . </manifest>
it is also possible to apply different themes to different activities by setting a theme on the
So, there we have the basics of applying a theme to an app. To completely customise the style of every possible widget will obviously take some time, but having the ability to apply an across-the-board style to all widgets of a particular type is both extremely powerful, and makes it much easier to maintain our code.
© 2011, Mark Allison. All rights reserved. This article originally appeared on Styling Android.
Portions of this page are modifications based on work created and shared by Google and used according to terms described in the Creative Commons 3.0 Attribution License
Themes by Styling Android, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. Terms and conditions beyond the scope of this license may be available at blog.stylingandroid.com.