Android Dev: mundane button making

BeforeOne of the parts of Android dev that I personally find the most challenging for a number of reasons is the mundane task of making the user controls. I’m not sure if the fact that it is also an area in which I am most lacking is a cause of this or it is an effect of it. Either way I’m going to walk you through the process I use to get it done.

For this example I’ll use the real world button that I’m avoiding working on by writing this. It’s the “Equivalent Parallel Conductors” button for the Conductor Size Selection calculator in Electrist.

I’m lucky enough to be cheating a little today and using as a base graphics that I toiled on years ago when making the original Palm OS version of Electrist. Unaltered, they don’t really suit the look of the Android version. I will eventually go back and rework them further, but today it’s just about getting the function into the software. I wasted my entire day yesterday trying to design pretty buttons from scratch that matched the rest of what I’ve attempted to culture throughout the app.

The Palm platform had a different way of visually handling the various states of the button. Android will have you specify a graphic for each possible state. I much as I’ve griped I still prefer Android’s approach. This allows the developer supreme freedom in creating a custom culture throughout their app.

In the case of a simple button this will use 3 separate images: normal, focused, and pressed. To be done by the book you will also need to have unique versions of this set of 3 images for each resolution your app supports. Any resolution that you do not directly support with it’s own images will use the supplied graphics, but scale them into twisted ugly mutants.

For more complex controls such as a CheckBox you will have each of these conditions for each of the possible states of the control. For the 2 (on/off) checked states of a CheckBox this means that for each of the screen densities that you support out of HDPI, MDPI, and LDPI you will need 6 graphics. To support all 3 densities, then, would require 18 unique images.

Create the Images

Rather than making a minimum of 9 different images for each button that I’m working on today I am going to rely on the knowledge that the vast majority of devices out there are HDPI and the ones that aren’t will soon be replaced by ones that are. Besides, I am a really bad at graphic design. Iconography is even more difficult. It’s a zen art. It is the haiku of digital graphic design. Today is an HDPI-only day.

Equivalent Parallel Conductors Button

Now that that’s all sorted, the next step would be to fire up the graphics editor of your choice and design the symbology for your button. As I said, I’m skipping this step here. I’m using my antique Palm bitmap as a starting point.

state layers

Since I’m a cheapskate with little discernible talent or skill in this field I’m using the freeware Gimp editor to work on my images. Previously, when I created the very first button for the app, I created 3 layers that I use in each graphic:

a gradient with lowered opacity in “lighten only” mode to provide a little shiny 3D attitude

a solid red with lowered opacity in “multiply” mode for the “selected” state

a solid dark gray with lowered opacity in “multiply” mode for the “pressed” state

So now, the assembly-line process I use for a simple button is:

icon pasted into Gimp

Paste the graphic into Gimp. This will inexplicably at first be a weird “floating layer” until I click the “new layer” icon at the bottom of the Layers window. Since the original bitmap is 22px square that is the size the layer will be even though the canvas size is 24px square. To get the layer to the full 24px I use the Layer > Layer to Image Size menu item.

I fill everything surrounding the original graphic with my special secret patented shade of gray. It can now be exported as btn_parallel_conductors_normal.png

layers for pressed state

Unhide the “pressed” and “sheen” layers and export as btn_parallel_conductors_pressed.png

Repeat with the “selected” and “sheen” layers for btn_parallel_conductors_selected.png

Now I’m thankfully done with the Gimp part.

Use the Images

Drag these 3 files into your project’s res/drawable/ directory. Be sure to refresh the project if it’s currently open in Eclipse so the IDE will know they’re there.

Next there needs to be a state list definition. Right-click on the res/drawable/ folder in Eclipse for New > File. My file will be called btn_parallel_conductors_states.xml and it goes a lil somethin’ like this:

btn_parallel_conductors_states.xml

1

2

3

4

5

6

7

8

9

10

11

12

13

<?xml version="1.0"encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">

<item android:state_focused="true"

android:state_pressed="false"

android:drawable="@drawable/btn_parallel_conductors_selected"/>

<item android:state_focused="true"

android:state_pressed="true"

android:drawable="@drawable/btn_parallel_conductors_pressed"/>

<item android:state_focused="false"

android:state_pressed="true"

android:drawable="@drawable/btn_parallel_conductors_pressed"/>

<item android:drawable="@drawable/btn_parallel_conductors_normal"/>

</selector>

The important thing here is that the specified focused and pressed states point to the appropriate drawable resource

In res/values/style.xml I apply the styles inherited from other like resources that I defined earlier on:

The important thing this time is that it calls out the style’s button property as the XML drawable file I just made. The style properties can all be defined right in the layout, but since so many of these objects will function visually identically there’s no reason to cut/paste/retype/clutter the layouts up with the same properties over and over. This makes adding it to the layout as simple as referencing the style name defined in the last step: {php theme=”classic”}{/php}

After - normalAfter - selected

Here is the layout with the new button in all it’s glory! Only 30-some more to go!