When you’re working with graphic assets in Android, it’s nearly impossible to avoid importing bitmap files in your project. And that’s ok because for a complicated design (with many shadows and textures for instance) it’s the right solution. Trying to make these graphics work with multiple screens though will eventually get ugly because you’ll have to use 3 or 4 versions for each bitmap. It makes sense then to use any non-bitmap solution where you can. Android’s layer-list is one of these powerful solutions.
What’s the design?
So, trying to have textures and shadows and other simlar cool stuff is impossible without bitmap files (at least I dont know any way to do it), but what about a rectangle with a gradient fill and a line on the top section? Have a look a the following image.
This could be used as a background for a navigation bar, or a button for example. If you can’t notice the line I’ve mentioned, I’ve zoomed in on the graphic so have another look.
Yes it may look tricky to have it working without exporting it as a bitmap and 9-patching it, but it’s actually not so hard. Having an xml based graphic for this kind of background will enable you to switch colors easily anytime you want without exporting a new bitmap from your editor. Obviously, you will not add yet another bitmap in every drawable directory of your project. All you need is one drawable file that can be included in your default drawable directory.
These are the 3 colors we will need
- For the line : #FF7A4D
- For the gradient’s start (top) : #8C2300
- For the gradient’s end (bottom) : #D34617
In your application you will probably add these as entries in your colors file but this is a quick tip so I’m going to skip this and hardcode them into our drawable.
What is a layer-list anyway?
A layer-list is based on the layers concept of image editors like Photoshop. You add items in the list and they will stay “on top” of each other unless you start defining their offset values to make them align exactly the way you want. The important thing is to remember that your first item (as defined in your xml) will always be the one on the back of all the others and your last item (as defined in your xml) will be the one in front of all the others.
The tricky part here is that you can’t define a line as a layer item. What you also can’t do is set the height for an item. So how can we build this graphic?
Our final result should consist of the gradient and on top of it a line. Unfortunatelly the line is not exactly at the top, it’s drawn with a padding of one pixel from the top so we will need the following shapes
- One shape to act as the dark line on top
- One shape to act as the light line right below the dark line
- One shape to act as the full gradient right below the light line (expanding to the bottom of the graphic)
Since you can’t draw lines or set heights, the two lines will also expand to the bottom of our graphic but only a part of them will be visible because other stuff will be on top of them.
<gradient android:angle=“270” android:startColor=“#8C2300” android:endColor=“#D34617”/>
The code block above is all you need to make the graphic look like our final result. After you define your root element as a layer-list and add the android namespace, you can start working on the three required items (layers).
The first item acts as our top line and it uses the gradient’s top color.
The second item acts as the second line, it uses the line color and it’s top padding is set to 1dp which means that the shape will start being drawn 1 pixel below the graphic’s top and it will cover the rest of the first item (making the first look line a line).
The third item acts as the gradient, it uses an angle of 270 and the two colors of the gradient. It’s top padding is set to 2dp so it will start being drawn 2 pixels below the graphic’s top and it will cover the rest of the second item (making it also look a line).
Saving this in your drawable directory will make it available to be set as a background in any component you want it.
It may look a hack to use 3 full shapes this way so if you know any other solutions feel free to share them in the comments.