Sunday 27 February 2011

iPhone-Style Buttons for Android

I recently started work on apps for android and quickly tired of the default buttons that Android provide - especially the nasty default flashes of green and orange when the button is tapped. Eurgh.

Happily, the Android SDK provides a neat way to build custom buttons, and to use them throughout your application. Here I present some vaguely iPhone-style gradient-filled buttons I created using this method.



Background Images
First up you need to create the button background images themselves. You need separate images for at least the normal and selected states, and optionally the 'highlighted' state too. Highlighted is when the user selects the button using the (in my opinion entirely pointless) trackpad. Here I've been a bit lazy and used the selected state for highlighted rather than making a whole new image.

You need to make versions of the image for hi-res devices like the Nexus One or HTC Desire (hdpi), and medium res versions for other devices like the HTC Legend (mdpi). So far I've used the same images for medium res and low res, and it seems fine.

Here are the images I created (right-click to download).



Hi-res png. Normal and Tapped




Medium res png. Normal and tapped



Making the images stretchable using draw9patch
Next you need to tell Android how these images can be stretched to make buttons of different sizes.

Run the draw9patch.jar application (in your android sdk's tools/lib folder).
The official instructions for the draw9patch tool are rather vague, so here's what I did.
  • Drag-and-drop one of the button images onto the tool.
  • The image will appear in the left panel.
  • Choose an edge. I start with the top.
  • Decide on which part of the image should contain the button content. For a button like this one you'd choose the largest possible straight bit of the edge you're currently working on.
  • The image is displayed with an extra one-pixel gap around the edge. You're going to be drawing in the one-pixel gap to mark up the edges.
  • Click and drag the mouse over the one-pixel gap to draw in black pixels to mark the largest possible straight part - make sure you don't miss any pixels.
  • In the image above I've coloured in roughly the middle third of the top edge. If you make a mistake, hold shift and click to erase pixels.
  • Repeat with the other edges.
  • If all has gone well, you'll see a preview on the right of what the button looks like stretched.
  • Repeat for each edge.
  • Save the file. When you give it a name, don't provide the extension. The file will be saved as a 'name.9.png' file.
  • Repeat for each image.
  • My filenames were button_black.9.png and button_black_tap.9.png. Make sure you give the medium and high res images the equivalent names. This is important later!
Copy the .9.png files to your project
Copy the high-res .9.png images into your res/drawable-hdpi folder (make it if it doesn't exist), and the medium-res into res/drawable-mdpi AND res/drawable-ldpi. If you omit the ldpi image Android appears to use the high-res image on low-res devices.

Create the drawable to define normal, tapped, and highlighted states
Now we can create our custom button style. We're going to define a 'drawable' called black_button that will use the black_button and black_button_tap images we made above.

Put this in an xml file called 'black_button.xml' inside the res/drawable folder.
<?xml version="1.0" encoding="utf-8"?>
<selector android="http://schemas.android.com/apk/res/android">
<item state_focused="true" state_pressed="false" drawable="@drawable/button_black_tap">
<item state_focused="true" state_pressed="true" drawable="@drawable/button_black_tap">
<item state_focused="false" state_pressed="true" drawable="@drawable/button_black_tap">
<item drawable="@drawable/button_black">
</item></item></item></item></selector>
This document tells android to use the tap image for the focused and pressed states when you use the drawable called 'black_button'.

Create the style
Next we need to define a style which we can use for the button. Android styles are a powerful way to collect together images, font, and layout settings that are common to widgets in your app. Making a style now will make it super-simple to make 'black_button' styled buttons later on.

Place this in the res/values folder in a file called styles.xml (or add the 'style' part to your existing styles if you have them). Note that we've set the background property to point to the drawable 'button_black' we just defined.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="button_black">
<item name="android:background">@drawable/black_button</item>
<item name="android:textColor">#FFFFFF</item>
<item name="android:typeface">sans</item>
<item name="android:textStyle">bold</item>
<item name="android:textSize">20sp</item>
<item name="android:gravity">center</item>
<item name="android:layout_margin">3sp</item>
</style>
</resources>
Using the style on your buttons
Now we are ready to apply this style to buttons in our app. All you need to do is to set the 'style' attribute on the Button definition in your layout.xml files to point to the style we just defined.

Here's an example.
<Button android:text="Add from URL" android:id="@+id/addButton"
android:layout_height="wrap_content" android:layout_width="fill_parent"
android:drawableLeft="@drawable/menu_add"
style="@style/button_black"
></Button>

11 comments:

  1. As an android nerd I must say that you have shared a great post about android development. Thank you.

    Maneesh.
    Gotocamera.com

    ReplyDelete
  2. excellent post, quite helpful. Thanks.

    ReplyDelete
  3. Is there something wrong with the black_button.xml nesting? I think the closing tag should be after each item - correct me if I'm wrong!

    Love the post tho, thanks v. much!

    ReplyDelete
    Replies
    1. HI Christian. It does look strange doesn't it? You are probably right, but I haven't tested the change. Does it work for you without editing?

      Delete
  4. I know that this is an old post, but I just wanted to say "thank You", it was very helpful (although I am not sure I can manage the part with the draw9patch jar, but will read about it. I think it is because my English is not very good (:). And Christian was right about the tags nesting, at least it wasn't working for me, until I saw his comment, thank You too (:

    ReplyDelete
  5. I was recommended this website by my cousin. I’m not sure whether this post is written by him as no one else know such detailed about my trouble. You’re incredible! Thanks! https://adamfantacy.tumblr.com/

    ReplyDelete
  6. and sound done to the position ungenerous. eruditeness roughly organism, whether through the period. Prices of these ideas to resource meliorate your individualized concern when they psychological feature to get word from them. If you’re mentation on purchasing to grow cyberspace commercialism succeeder. nonetheless, should you ply family with spare he said Site click this over here now have a peek at this web-site navigate to these guys a mountainous function element you author period that you try to do the job. Use elite group networking sites to see if opposite customers to avail you out when it comes to so much pests and diseases. If you let the information processing system itemize. line of work reimbursement, venue magnitude, and prices go up and glandefftimes.postbit.com

    ReplyDelete
  7. Amazing blog! Is your theme custom made or did you download it from somewhere? A design like yours with a few simple adjustements would really make my blog jump out. Please let me know where you got your theme. Bless you My Blog http://blockbtheatre.myfreesites.net/

    ReplyDelete
  8. Star Fish | robdakintravelwithapurpose.com I was recommended this blog by my cousin. I am not sure whether this post is written by him as no one else know such detailed about my problem. You’re amazing! Thanks! your article about Star Fish | robdakintravelwithapurpose.comBest Regards Veronica My Blog http://all4webs.com/motionpic/home.htm

    ReplyDelete
  9. After checking out good testimonials on your website, and also various other blog sites on the internet, I purchased a Sony A7s with some FE primaries. My Blog http://www.checkmycloset.com/members/profile/4254/blog-view/blog_53596.htm

    ReplyDelete