Working with Android Shape Drawables

Recently I’ve been working with Shape Drawables in Android and have found them to be quite handy to utilize for certain areas of your Android UI. Shape drawables are basic shapes that you can define using XML. They’re useful for many reasons:

  • They ‘just work’ with multiple device densities.
  • No need for bitmap resources, which saves space in your app.
  • They’re flexible to any screen size, so you don’t have to deal with those pesky 9-patches.

Over the past few months I’ve been responsible for implementing a redesign of the Notifications view in WordPress for Android. The design included special borders for when you are viewing a comment reply:

comment-reply-shape-drawable-background

The background for the comment needed to meet the following qualifications:

  • Contain a left margin so that the bar on the left appeared indented.
  • Have a thick border on the left, and a thin border at the bottom (but no border on the top and right side).
  • Work with multiple colors, since an unapproved comment will show a yellow background.

So I got to work on the shape drawable. After a few issues getting the borders to line up correctly, this is the XML that I ended up with:

comment_reply_background.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/white" />
        </shape>
    </item>
    <item
        android:left="@dimen/margin_extra_large"
        android:right="@dimen/margin_extra_large"
        android:top="@dimen/margin_large">
        <shape android:shape="rectangle">
            <solid android:color="@color/blue_light" />
            <padding
                android:bottom="1dp"
                android:left="20dp" />
        </shape>
    </item>
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/white" />
        </shape>
    </item>
</layer-list>

The most interesting part of the XML is the second item in the layer-list, which is what takes care of drawing the borders. Note the left, right and top margins that indent the borders. Next, a rectangle is drawn that includes a 1dp padding for the bottom border, and pads by 20dp on the left side which when accounted for @dimen/margin_extra_large (which is 16dp) will give us a visible 4dp border.

The last rectangle shape in the layer-list will fill in the rest of the non-bordered area in with white. Bingo!

Doing the yellow version for unapproved comments was as easy as swapping out the colors and removing the indent because it wasn’t needed for unapproved comments:

comment_reply_unapproved_background.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/white" />
        </shape>
    </item>
    <item
        android:left="@dimen/margin_extra_large">
        <shape android:shape="rectangle">
            <solid android:color="@color/orange" />
            <padding
                android:bottom="1dp"
                android:left="20dp" />
        </shape>
    </item>
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/orange_light" />
        </shape>
    </item>
</layer-list>

Shape drawables certainly don’t work for every element in your Android UI, but they are very handy when they do. Keep them in mind as you are constructing the UI in your app!

If you’re interested in seeing other examples of shape drawables, there’s plenty more in the WordPress for Android repo on GitHub.