The Butt is On
I’ve been optimizing and cleaning up the AlertMe for Android app to put into the Google Play marketplace, and after using drawable shape
s I figured that it was time to throw away those duplicate button images. The original used a technique familiar with web developers/designers: change the whole image according to the state of an element, in this case a button:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_enabled="false" android:drawable="@drawable/ic_home_status_home" /><!-- default state --> <item android:state_pressed="true" android:state_enabled="true" android:drawable="@drawable/ic_home_status_home_pressed" /><!-- pressed state --> <item android:state_focused="true" android:state_enabled="true" android:drawable="@drawable/ic_home_status_home_focus" /><!-- focus/hover state --> <item android:state_enabled="true" android:drawable="@drawable/ic_home_status_home" /><!-- default state, just in case --> </selector> |
All rather neat so far. Now, developing for mobile you start to appreciate things like space – particularly when you phone is rather low on it (true story) – and the same image is kind of wasteful. Images are the worst to keep around for mobile application because they can only compress so far – while text is rather easy. When I did the Letchworth Beer Fest app I used shape
s to define a background rectangle and a single image over the top, so now I save on 2 less images and a cleaner looking ‘button’ to boot:
<!-- excerpt for 'pressed' state: --> <item android:state_pressed="true" android:state_enabled="true"> <layer-list> <item> <shape> <gradient android:startColor="@color/button_pressed_light" android:endColor="@color/button_pressed_dark" android:angle="270" /><!-- gradient box, just because --> <stroke android:width="1dp" android:color="@color/button_pressed_dark" /><!-- 1dp border --> <corners android:radius="3dp" /><!-- neat - round corners --> <padding android:left="10dp" android:top="10dp" android:right="10dp" android:bottom="10dp" /> </shape> </item><!-- end box --> <item><!-- now overlay the image on top: --> <bitmap android:src="@drawable/ic_home_status_home" android:gravity="center" /> </item> </layer-list> </item> <!-- now an excerpt for default state --> <item android:state_enabled="true"> <layer-list> <item> <shape> <solid android:color="@color/button_default_light" /><!-- can be anything, but I've made it transparent --> <corners android:radius="4dp" /> <padding android:left="10dp" android:top="10dp" android:right="10dp" android:bottom="10dp" /> </shape> </item> <item> <bitmap android:src="@drawable/ic_home_status_home" android:gravity="center" /> </item> </layer-list> </item> |
List item select?
When I tried to use the same states for list items in my odd/even rendered lists, I switched over from setBackgroundColor
to setBackgroundResource
. However I found there wasn’t a change in the pressed or focus states. Some Googling later I found these states worked for me:
<?xml version="1.0" encoding="utf-8"?> <!-- for the 'odd' background; you can guess there is another file using '@color/menu_even' --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_enabled="false" android:state_pressed="false"> <shape> <solid android:color="@color/menu_odd" /> </shape> </item> <item android:state_pressed="true" android:state_enabled="true"> <shape> <gradient android:startColor="@color/button_pressed_light" android:endColor="@color/button_pressed_dark" android:angle="270" /> </shape> </item> <item android:state_focused="true" android:state_enabled="true"> <shape> <gradient android:startColor="@color/button_selected_light" android:endColor="@color/button_selected_dark" android:angle="270" /> </shape> </item> <item android:state_selected="true" android:state_pressed="false"> <shape> <gradient android:startColor="@color/button_selected_light" android:endColor="@color/button_selected_dark" android:angle="270" /> </shape> </item> <item android:state_enabled="true"> <shape> <solid android:color="@color/menu_odd" /> </shape> </item> </selector> |
The result is now a more unified look-and-feel as the button and list item states use the same focused and pressed highlighting colours.