Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Buttons in Android: How to get border/edge/frame when I read the background from xml?

Tags:

android

Using Android Shapes in xml I have defined a gradient which I use as the background for a button.

This all works nice, but there's no edge surrounding the button. I would like it to look similar to the normal Android button but I need more flexibility to control the color and look.

The shape is defined as follows:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <gradient android:startColor="#FFFFFF" 
        android:endColor="#00FF00"
        android:angle="270" />
    <corners android:radius="3dp" />
    <stroke android:width="5px" color="#000000" />
</shape>

I would expect the border to be set in the xml. Why doesn't "stroke" fix it? Stroke doesn't seem to do anything. I checked the Android Developer spec, but couldn't find the answer there: http://developer.android.com/guide/topics/resources/drawable-resource.html

I have also looked through all the properties of the Android Button, but as expected there's no such parameter, probably since it's built into the normal Android button. Btw, I checked ImageButton properties too.

Can someone please help? I know there's the alternative to make an image with proper edges and use an ImageButton, but there really should be a way to fix this programmatically.

Thanks! Anna

like image 610
Anna Avatar asked May 26 '10 11:05

Anna


3 Answers

I had this problem a while ago. While I don't quite remember why I made each decision, the way I solved it was to use a a shape layer-list. This lets you stack one shape on top of another. For example, the following XML creates a shape with a solid black outline 2px wide, with a 'grey to white to grey' gradient across the middle:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <padding android:left="1dp"
                android:top="1dp"
                android:right="1dp"
                android:bottom="1dp"/>
            <solid android:color="#FF000000"/>
            <corners android:radius="3dp"/>
        </shape>
    </item>

    <item>
        <shape>
            <padding android:left="2dp"
                android:top="2dp"
                android:right="2dp"
                android:bottom="2dp"/>
            <gradient android:startColor="#FFB0B0B0"
                android:centerColor="#FFFFFFFF"
                android:endColor="#FFB0B0B0"
                android:angle="315"/>
        </shape>
    </item>
</layer-list>

If you want to be able to change that color dynamically at runtime, then things get a lot messier. Again, the details of why I had to do things a certain way are hazy, but I ended up having to create a custom view class which contained a custom ShapeDrawable. I started off looking at the examples from the ApiDemos app which comes with the SDK - it's a very good resource.

EDIT: Another reason your stroke might not be appearing is that you forgot the android: before the color="...." bit.

like image 60
Steve Haley Avatar answered Nov 16 '22 11:11

Steve Haley


I've had the same problem, what i observed is stroke is not applying to button as border at design time but at run time i see the border.

I jst used the following same code

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" android:padding="10dp">
    <solid android:color="@color/black" />
    <stroke  android:width="1px" android:color="@color/red" />

</shape>

as steve hanley said abvoe you miss the android: for the color attribute.

Hope this helps somebody....

like image 6
praveenb Avatar answered Nov 16 '22 11:11

praveenb


Probably much to late, but you have to add an extra ff before the color.

<stroke android:width="5px" color="#ff000000" />

Greets

like image 3
Dusty Avatar answered Nov 16 '22 11:11

Dusty