views:

17998

answers:

4
+3  A: 

Nope, I think you have the right answer there. Be grateful you only need three states -- there are other possible ones (e.g., disabled, selected).

You can certainly just set the background to be a solid color, which is simpler, but it means you won't see focus, clicks, etc.

CommonsWare
Bummer! Is there a way to somehow just specify the background for all 3 images, so I can just use the default button image without having to make any custom ones at all? (And of course still support the various states)
Mike
Uh, the images *are* the background, so I'm afraid I don't understand your question.
CommonsWare
Right, what I mean is, could I make a transparent image that looks like a button, and then somehow just swap out the colors underneath? That way I'd only need one custom image, even though I'd still have to specify three+ different states. I know I could do this by making three different XML drawables, but it would be nice to do with just one drawable.
Mike
How can you make "a transparent image that looks like a button"? Wouldn't it be, um, transparent? ;-) Honestly, I still can't quite picture what you're describing.
CommonsWare
Easy: by making it not 100% transparent but say 80% transparent and 20% button shaped. And if you still can't imagine it here is an example:http://uiq3.svn.sourceforge.net/viewvc/uiq3/trunk/JavaME/FX-602P/src/main/resources/qvga/highlight-0.png
Martin
+45  A: 

I discovered that this can all be done in one file fairly easily. Put something like the following code in a file named custom_button.xml and then set background="@drawable/custom_button" in your button view:

<?xml version="1.0" encoding="utf-8"?>
<selector
    xmlns:android="http://schemas.android.com/apk/res/android"&gt;

    <item android:state_pressed="true" >
        <shape>
            <gradient
                android:startColor="@color/yellow1"
                android:endColor="@color/yellow2"
                android:angle="270" />
            <stroke
                android:width="3dp"
                android:color="@color/grey05" />
            <corners
                android:radius="3dp" />
            <padding
                android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp" />
        </shape>
    </item>

    <item android:state_focused="true" >
        <shape>
            <gradient
                android:endColor="@color/orange4"
                android:startColor="@color/orange5"
                android:angle="270" />
            <stroke
                android:width="3dp"
                android:color="@color/grey05" />
            <corners
                android:radius="3dp" />
            <padding
                android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp" />
        </shape>
    </item>

    <item>        
        <shape>
            <gradient
                android:endColor="@color/blue2"
                android:startColor="@color/blue25"
                android:angle="270" />
            <stroke
                android:width="3dp"
                android:color="@color/grey05" />
            <corners
                android:radius="3dp" />
            <padding
                android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp" />
        </shape>
    </item>
</selector>
Mike
Thanks. This is very useful
olore
That works well for background color - can you set the text color in the same way?
Rachel
where do you get all the colors?
gregm
you can change those to be whatever you want. You can either change the code to use the hex values directly, or just define your own in colors.xml.
Mike
+3  A: 

Mike, you might be interested in color filters. You can play with them to achieve the color you want.

An example:

button.getBackground().setColorFilter(new LightingColorFilter(0xFFFFFFFF, 0xFFAA0000));

Tomasz
+14  A: 

Following on from Tomasz's answer, you can also programmatically set the shade of the entire button using the PorterDuff multiply mode. This will change the button colour rather than just the tint.

If you start with a standard grey shaded button:

button.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);

will give you a red shaded button,

button.getBackground().setColorFilter(0xFF00FF00, PorterDuff.Mode.MULTIPLY);

will give you a green shaded button etc., where the first value is the colour in hex format.

It works by multiplying the current button colour value by your colour value. I'm sure there's also a lot more you can do with these modes.

conjugatedirection
Oh, I should add that with this method you won't need 3 drawables, as it applies the colour transform after the highlight/selection. The resulting colour might vary but the colour tint should carry through.
conjugatedirection
Wow, just tried that out and it is totally fantastic. Thank you! Do you happen to know if there's a way to accomplish it via xml somehow?
Mike
Guys, check it on HTC Desire! They have different standard buttons. My buttons using this code look awefull there WHEN setting a certain layout_width like "40dp". With "wrap_content" it's fine.
OneWorld
Confirmed, this solution doesn't work on HTC Sense UI very well
Mike