Custom Spinner with rounded corners, stroked edge

2019-03-13 09:46发布

问题:

I want my Spinner to have a black gradient background with white text on the left and a selector icon on the right (a white downwards pointing triangle). As I see it there are two ways of going about this:

  1. If I set the background to an xml drawable resource I can make my Spinner look perfect, but then I need to somehow add the white triangle on the right, which I don't know how to go about:

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <gradient
                android:startColor="#343434"
                android:endColor="#171717"
                android:angle="270" />
            <stroke
                android:width="1dp"
                android:color="#ffffff" />
            <corners
                android:radius="4dp" />
            <padding
                android:left="3dp"
                android:top="3dp"
                android:right="3dp"
                android:bottom="3dp" />
        </shape>
    </item>
    </selector>
    
  2. I create a 9-patch image which includes the triangle and then use xml to round the corners and add a stroke to the image. I have had a go at this but was unable to make it work:

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="@drawable/spinnerblack" >
            <stroke
                android:width="1dp"
                android:color="#ffffff" />
            <corners
                android:radius="3dp" />
            <padding
                android:left="3dp"
                android:top="3dp"
                android:right="3dp"
                android:bottom="3dp" />
        </item>
    </selector>
    

Could someone either tell me what I can do for method 1 or what I have done wrong in method 2? I would prefer not to have to add the stroke and rounded corners in my 9-patch image because I don't think it ever looks as good. Also, I would prefer method 1 to method 2. Any help much appreciated.

回答1:

I've done something similar to method 1 in my app. Basically you need to combine your selector with a layer-list:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <layer-list>
            <item>
                <shape>
                    <gradient
                        android:startColor="#343434"
                        android:endColor="#171717"
                        android:angle="270" />
                    <stroke
                        android:width="1dp"
                        android:color="#ffffff" />
                    <corners
                        android:radius="4dp" />
                    <padding
                        android:left="3dp"
                        android:top="3dp"
                        android:right="3dp"
                        android:bottom="3dp" />
                </shape>
            </item>
            <item
                android:top="12dp"
                android:right="15dp">
                <bitmap android:src="@drawable/arrow_bitmap"
                        android:gravity="top|right" />
            </item>
        </layer-list>
    </item>
</selector>

In my xml I also added a third layer containing a <shape> that is invisible (i.e. its alpha is set to 0) but adds padding.