Ryan Harter

Freelance Android Developer

Taking Advantage of Android Styles

| Comments

One of the biggest differences between a good app and a great app is a consistent UI.  This can often be a difficult thing to accomplish when you consider how we, as developers, work on apps.  We tend to work on one screen at a time and, for lone developers, that can often lead to making minor changes as we work on the app and think of cool new things. Fortunately, Android has facilities that make it super easy to get a unified style throughout your app and actually reduces the amount of code you have to write.

The Layout

Lets start out by looking at the layout.  Through no fault of my own, my designer showed the client grouped text entry fields and she loved it.  So now I’m developing an app with custom non-Holo EditText fields everywhere and I have to make sure they look great. This is easily achieved with Styles.  Check out how easy it makes the layout code for the app in the screenshot above.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    <!-- Input Group -->
    <EditText style="@style/Widget.Group.Top" />
    <EditText style="@style/Widget.Group" />
    <EditText style="@style/Widget.Group.Bottom" />

    <!-- Single item -->
    <EditText style="@style/Widget.Group.Single" />

This is a simple example, but you can see that the layout consists of nothing but styled EditText fields.

The Styles

Now lets take a look at the styles for this.  You could easily achieve that layout by setting a background image on each edit text, along with the size and margins, but to make sure all grouped text fields throughout the app look great, and the same, you should extract these attributes into Styles.  As you can see in the code, we define the style for Widget.Groups in styles, and then all we have to do in the layout is set the appropriate style and we will always have a consistent layout.
<?xml version="1.0" encoding="utf-8"?>
	<style name="Widget.Group" parent="@android:style/Widget">
		<item name="android:layout_width">match_parent</item>
		<item name="android:layout_height">46dp</item>
		<item name="android:layout_marginLeft">10dp</item>
		<item name="android:layout_marginRight">10dp</item>
		<item name="android:layout_marginTop">-1dp</item> <!-- Ensures we don't get a 2 dp top stroke -->
		<item name="android:padding">4dp</item>
		<item name="android:background">@drawable/bg_input_group</item>

	<style name="Widget.Group.Top">
		<item name="android:layout_marginTop">10dp</item>
		<item name="android:background">@drawable/bg_input_group_top</item>

	<style name="Widget.Group.Bottom">
		<item name="android:background">@drawable/bg_input_group_bottom</item>

	<style name="Widget.Group.Single" parent="Widget.Group.Top">
		<item name="android:background">@drawable/bg_input_group_single</item>

Implicit Inheritance

One of the great things about Android’s Style resources is inheritance.  As you can see in the code above, we use a base Widget.Group style, which inherits from the base Widget style in Android.  This will set the height of all of the fields, also the horizontal margins and background for a standard widget.  This background is for widgets nested within a group (i.e. the middle row) and includes the white background and gray border.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"

	<solid android:color="@android:color/white" />

	<stroke android:width="1dp"
		android:color="#ccc" />

The styles for Top and Bottom widgets inherit from Widget.Group implicitly due to the dot namespacing.  This is a little known (at least to me before writing this article) secret that is nice for saving some typing time but can cause problems if you aren’t careful with your packages (notice how Widget.Group needs to explicitly have the “@android:style/Widget” parent since it’s in a different package). As you can see, for the top and bottom fields, this inheritance help us keep things consistent because all we have to change is the background image and margins.

Explicit Inheritance

The “Widget.Group.Single” is a great example of explicit inheritance.  In this case it would be confusing to call the style “Widget.Group.Top.Single” but we want to inherit the top group margins of the Top cell to keep things consistent.  We do this by explicitly defining the inheritance of a style using the “parent” attribute.
<style name="Widget.Group.Single" parent="Widget.Group.Top">
	<item name="android:background">@drawable/bg_input_group_single</item>

Use Style

As tempting as it can be to skip styles and just copy and paste attributes throughout your UI, I would encourage everyone to use styles instead.  Not only does it make it super easy to make slight changes, but you can also use Android’s Resource Engine to easily define styles for different platforms and ensure that you will have a consistent look and feel throughout your app.  This will make users feel more comfortable navigating your app and really gives it that high level of polish.


Read the docs - Style Resource Guide
Reference the source of Android’s built in styles - AOSP Styles.xml