In recent articles on Styling Android I have diverged a little from pure UI and covered some more subtle aspects to improve your UX. In this series we’re going to return to something that was covered in the very first post to Styling Android: Drawables. Previously we have looked at how shape drawables can be used instead of bitmaps to provide better scaleability of your UI components between different devices & from-factors. In this series we’ll look at some further tricks that you can use to get the most out of shape drawables.
To begin, we’re actually going to look at a technique using a bitmap drawable, but we’re going to use a drawable resource to control how the bitmap is rendered. There is an excellent resource at subtlepatterns.com which provides free graphics that we can use as backgrounds. I have selected Knitted Netting and saved it to my res/drawable-mdpi folder. If we were to use this as the background to a layout, it would not work very well because the graphic itself is actually on 8 x 8 pixels, and is designed to be tiled in order to produce the required background pattern. Setting the android:background attribute on a View will display a single copy of the bitmap centred in the layout and stretched to fit:
There is a simple way that we can create a tiled version of this, we create a new drawable resource in res/drawable/backgroundpattern.xml:
<?xml version="1.0" encoding="utf-8"?>
This that we are wish to tile the image. There are other tileModes which I won’t go in to here, but are detailed here.
If we use this as our background instead, we get a nice subtle background pattern:
There is only one problem with this: occasionally it doesn’t work! There is a known bug in 3.x where sometimes tiled drawables are stretched rather than tiled (it has been fixed in 4.x). This behaviour can be seen when launching the Play Store (formerly Android Market) on a Honeycomb device. The background pattern in the ActionBar is stretched rather than tiled during app startup:
When the app is fully running the pattern is tiled as it should be:
If ever you encounter this issue, there is a relatively straightforward work-around: we must programatically re-apply the tiling to the background image:
protected void onResume()
final ActionBar actionBar = getActionBar();
background.setTileModeX( android.graphics.Shader.TileMode.REPEAT );
actionBar.setBackgroundDrawable( background );
This solution comes courtesy of this answer to a question on StackOverflow.
We now have a nice tiled background which works even when applied to the ActionBar on a Honeycomb device. In the next article in this series we’ll look at putting a fancy border around a panel.
The source code for this article can be found here.
© 2012 – 2014, Mark Allison. All rights reserved.
More Drawables – Part 1 by Styling Android is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. Permissions beyond the scope of this license may be available at http://blog.stylingandroid.com/license-information.