This article is part of our Academy Course titled Android UI Design – Basics.
In this course, you will get a look at the fundamentals of Android UI design. You will understand user input, views and layouts, as well as adapters and fragments. Check it out here!
Table Of Contents
In the previous articles, we talked about layout and how we can organize our
Views so that we can create appealing user interfaces. We saw there are several
layout managers and
provided by the Android SDK and that, if they are not enough, we can create custom
layout managers and
Views. We also talked about
drawable, which is very useful when we want to customize some widget.
In this article we will describe how we can use
theme. This is an important aspect when developing an app because using style and theme we can brand our app and have an harmonious look.
While the layout and the
Views specify the structure of the user interface, styles and themes define their look. What is a theme in Android?
A theme is a set of styles and can be applied to the whole app or to a single
Activity. It helps to create an appealing user interface. A style, on the other hand, specifies a set of properties that have effects on how a
Window looks like. These properties specify the font size, the font family, the background color, font color and so on. We can imagine that a style is like a CSS in a web page, it separates the content structure from how it is displayed on the screen.
When we create a layout in XML we use
layout managers and
Views. When using
Views we could specify for example the background color, the font color,
View size and so on. For example let us suppose we have a simple
TextView like the one shown below:
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#FF0000" android:text="Hello style" android:textColor="#FFFFFF" android:textSize=""14sp"" > </TextView>
Looking at the code above we notice there are some mistakes: we added to the
View not only the information regarding its content but also information about how it looks like and we hard-coded it directly. This is a very bad practice, because if we want to change the text color we should look for each
TextView in our user interface definition.
Moreover, in a consistent and appealing user interface where text messages have all the same size, we will have to replicate the text size information for each
TextView in our layout. This is a classic example where using a style would avoid duplication of data, separate the layout structure from its appearance and improve the XML file readability.
Styles and themes are very similar concepts: when we apply a style to an
Activity or an application, instead of applying it to a single
View, we call it a theme. In this case every property of a
View that belongs to the
Activity/application will be specified by the
Activity/application style. For example we could define text size and color in a style and apply it to an
Activity. In this way all the texts will look like as defined in the style.
Now that we know what a style is, we have to define it inside our app. To do this, we have to create an XML file under
res/values. We can choose the file name as we prefer but it must have the
.xml extension. A style is defined inside the resource tag. So we have:
<resources xmlns:android="http://schemas.android.com/apk/res/android" > <style name="MyTextStyle" parent="@android:style/TextAppearance" > <item name="android:textColor">#FF0000</item> <item name="android:textSize">14sp</item> </style> </resources>
In this way we have defined a new style called
MyTextStyle and we have defined some properties as specified in item tags. Notice that in the style definition we used the parent attribute. This is an optional attribute which can be usedf if we want the defined style to inherit its properties from the parent style. Then, inside the style definition, we can override the parent properties. Under the style tag we defined two items so we specified two properties.
item tag has a name attribute that defines the property name. This is the name of the property we want to apply the style, and the tag content is the property value. In our case, we defined a property called
android:textColor assigning to it the value
#FF0000 and another one called
android:textSize and we assigned the value
As we have seen before, style can inherit from a parent style, using parent attribute in
style tag. So we can create an hierarchical structure with styles. There is another way to implement an hierarchical structure inside the same XML style file: we can simply use
For example, we can suppose we want to create another style called
MyTextStyleHuge that inherits from
MyTextStyle but overrides the text size:
<style name="MyTextStyle.MyTextStyleHuge" > <item name="android:textSize">30sp</item> </style>
and we can continue in this way adding new inheritance.
Each style defines the values of a set of properties using item tag. The property names are the names of the properties defined by a
View. For example, looking at
TextView we notice it has a set of properties described in the documentation in the XML attributes section. If we want to define the style of one of this property, we have to use the same name in the attribute name of
Looking at the example above, we used the properties
android:textColor, they are two properties of the
TextView according to the documentation: the first one used to define the text size and the other one for text color.
Once we have defined our style we have to apply it. As said before we can apply it to a single
View, to an
Activity or to an application. For example if we want to apply the style to a single
View we use
style attribute in this way:
<TextView style="@style/MyTextStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Text with style" />
Now we applied
MyTextStyle to the
TextView. These two ways are equivalent:
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello without style" android:textColor="#FF0000" android:textSize=""14dp"" >
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Text with style" style="@style/MyTextStyle"/>
In the left side we used a bad practice that we should avoid, while on right side we used a best practice. Running an app with these two
TextView in the layout we have:
As you can notice the result is the same for both
We know a theme is a special style that is applied to an
Activity or to an application instead of a single
View. A theme is always a style and when we want to define a theme we use the same technique used before when defining a style, so we create a XML file under
res/values. Android provides a large collection of themes and styles that we can use or override customizing them.
Let us suppose we want to create a theme for all the application that sets the background to green. In this scenario, we define a style called
AllGreen in this way:
<style name="AllGreen" parent="@android:style/Theme.Black" > <item name="android:background">#00FF00</item> </style>
and then we apply it to the application in the
<application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AllGreen" > </application>
Running an app like that we will have the following result:
As a result the
Activity background is green as we wanted. We have defined before a style for
TextView and now we would like to use it in our theme. To do it, we have to modify it a little bit:
<resources xmlns:android="http://schemas.android.com/apk/res/android" > <style name="MyTextStyle" parent="@android:style/Widget.Text<code>View</code>" > <item name="android:textColor">#FF0000</item> <item name="android:textSize">14sp</item> </style> <style name="AllGreen" parent="@android:style/Theme.Black" > <item name="android:background">#00FF00</item> <item name="android:textViewStyle">@style/MyTextStyle</item> </style> </resources>
Running the app we have:
By now we used just solid color for the background and we have seen it is easy to change the background, but what if we want to use a gradient color?
In the previous article we described how to create a gradient: we have to create a file with XML extension under
res/drawable directory; we call it
<shape xmlns:android="http://schemas.android.com/apk/res/android" > <gradient android:endColor="#AA0000" android:startColor="#FF0000" android:type="linear" /> </shape>
Now we have to reference it in our style and for simplicity we can create another style file called
<resources xmlns:android="http://schemas.android.com/apk/res/android" > <style name="RedGrad" parent="@android:style/Theme.Black" > <item name="android:background">@drawable/gradient_red</item> </style> </resources>
As you can notice, we referenced the
drawable we created under the
drawable directory, using
@drawable/file_name. Running an app with this style we have:
Until now, whenever we defibed colors or font sizes, we used some hard coded values. Even if this is possible, it is not recommended for several reasons:
- If we want to change the color or a font size for example we have to look for these values in the style file.
- We would like to change the font size and colors according to the platform version for example or according to the screen dimensions.
So it is a good practice to move the color definition and/or the font size and so on to an external resources and reference them in the style.
So let us rewrite the text style we used before where this time we write the style in an XML file called
<resources> <style name="MyTextStyle1" > <item name="android:textColor">@color/red</item> <item name="android:textSize">@dimen/myTextSize</item> </style> </resources>
In this style we referenced an external resource that sets the text color and the text size. In this case, we have to create two files: one that we can call
colors.xml containing the color definition and another one containing the dimension called
<resources> <color name="red">#FF0000</color> </resources> <resources> <dimen name="myTextSize">14sp</dimen> </resources>
We now know that we can reference external resources using the
@ symbol, but sometimes we want to reference a single style element not the whole style.
For example, we want to reference the current text color, but we do not know which one will be used by the OS. How can we do it? Well Android provides the
? symbol, which we can use to access a single element. For example we can suppose we want to set the text color value to one defined in Android OS:
<style name="TextRef" > <item name="android:textColor">?android:attr/textColorLink</item> </style>
Using this notation, we set the current text color to the default text color used for links. Running the app we have:
Android provides an interesting feature that is useful when we want to create an app for different devices that can run on different Android versions.
Until now we used just
res/values and we created several files that represent styles, dimensions, colors and so on. Android can use different resources according to the platform version, so we could adapt, for example, our themes and styles to the platform version, or we can even create a different style with different colors depending on the platform.
We know that newer Android version introduced some new features, APIs and resources including styles and themes. We could use newer themes when our app runs on devices that have a new Android version. At the same time, we want to keep the compatibility towards older Android versions. Using platform dependent resources we can achieve this goal.
In order to create a resource set that is dependent on the platform version we have to create a directory under
xx is the API level; for example if we want to create a resource set that is suitable for Android 3.0 (API level 11) or higher, we can create a directory called
values-v11. Under this directory we create style and themes. If we notice when we use Eclipse as IDE it creates two themes by default, one under
<style name="AppBaseTheme" parent="android:Theme.Light">
and another one under
<style name="AppBaseTheme" parent="android:Theme.Holo.Light">
As you can see, these two themee have the same name but inherit from different parents.
We can not only specify our theme according to the platform version but also according to the screen size. For example, if we want to apply our theme when the smallest screen size is at least
600dp, we can create a directory called
values-sw600dp and create under it our style file. This style and theme will be applied only when the device smallest screen size is at least
600dp. This technique is useful when we want to provide different style/theme according to the screen size. We could, for example, have only one style/theme defined in
res/values and provide different text size according to the screen size. In this case we can only create a file called
We now know how to use styles and themes and it is useful to recap some basic rules we should follow:
- Do not use hard coded values for colors, size and so on.
- Define a style or a theme and use
style=”...”in the widget definition to reference the style.
- In the style definition do not use values directly in the XML file but reference theme using external resources. For example reference a color using
- Provides different style or theme according to the platform version.
- Provides different resources according to the screen size.
This was a lesson on how to use Android Themes and Styles. You may download the source code here: themeStyle.zip