Spinner does not apply dropDownSelector attribute
Asked Answered
Z

4

13

I'm using spinner and want to add spinner - to change behavior depends of states(focused, pressed)

sample project is here https://github.com/vovs/spinner_issue

My code:

activity_main.xml

<Spinner
        android:id="@+id/spinner"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="30dp"
        android:spinnerMode="dropdown"
        android:dropDownSelector="@drawable/spinner_state" />

spinner_state.xml

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_enabled="false"
        android:drawable="@color/black" />
    <item
        android:state_pressed="true"
        android:state_enabled="true"
        android:drawable="@color/red" />
    <item
        android:state_focused="true"
        android:state_enabled="true"
        android:drawable="@color/red" />
    <item
        android:state_enabled="true"
        android:drawable="@color/gray" />
</selector>

AndroidManifest:

<uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="16" />

So, if I run app in emulator Android 4.0.2 API 14 and try to select some item or scroll using wheel of my mouse no any effect, that I set in selector(when press or scrolling - items should be red, but it is blue - default for ICS color).

For Android 2.2 API 8 when press or scroll using wheel(in this case state is focused) color is yellow[orange](default color for Android 2.2)

How to enable selector for spinner?

enter image description here

Zucchetto answered 6/2, 2013 at 20:7 Comment(0)
W
9

also an official bug... https://code.google.com/p/android/issues/detail?id=24922

what helps:

<resources>
    <style name="Theme.MyTheme" parent="@android:style/Theme.Holo.Light">
        <item name="android:dropDownListViewStyle">@style/Theme.MyListView</item>
    </style>

    <style name="Theme.MyListView" parent="@android:style/Widget.Holo.Light.ListView">
        <item name="android:listSelector">@drawable/orange_list</item>
    </style>
</resources>

good luck!

Winery answered 26/10, 2013 at 13:43 Comment(0)
U
3
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true" android:drawable="@color/lighter_gray_no_transparent" />
    <item android:state_selected="true" android:drawable="@color/lighter_gray_no_transparent" />
    <item android:state_pressed="true" android:drawable="@color/lighter_gray_no_transparent" />
    <item android:drawable="@android:color/transparent"/>
</selector>

<color name="lighter_gray_no_transparent">#FFDDDDDD</color>

set backgroud selector for your item view, that's all. Work for me. The color alpha value should be FF, or it will show orange background, left one color value is #FFDDDDDD, the right one is #55DDDDDD

enter image description here enter image description here

Unsightly answered 3/12, 2014 at 3:43 Comment(0)
P
1

There may be other ways but here's what I understand from using one of the Generators.

Declare your own style for the spinner in your res/values/styles.xml pointing to your drawable.

<style name="myCustomSpinner" parent="android:Widget.Holo.Light.Spinner">
    <item name="android:background">@drawable/spinner_state</item>
</style>

Create res/values/themes.xml and declare your own theme that inherits from the current theme. Within this theme, add an item for each attribute you're modifying and point it to your custom style from the last step. I think this could go in the styles file if you wanted, but since the generator separates them I follow suit.

<style name="myCustomTheme" parent="android:Theme.Light">
    <item name="android:dropDownSpinnerStyle">@style/myCustomSpinner</item>
</style>

In your AndroidManifest, add android:theme="@style/myCustomTheme" to the opening application tag.

Your values for parent will depend on how the project is setup and I think this will style of the spinners in your project and not just one. Try it out and let me know what you get.

Pokeweed answered 12/8, 2013 at 17:25 Comment(0)
G
0

Here is another solution similar to what es0329 gave:

    <style name="Base.Theme.SpinnerDemo" parent="Theme.Material3.DayNight.NoActionBar">
        <item name="android:dropDownListViewStyle">@style/My.Theme.Spinner</item>
    </style>

    <style name="My.Theme.Spinner" parent= "android:Widget.ListView">
        <item name="android:divider">@null</item>
        <item name="android:listSelector">@drawable/spinner_selector</item>
    </style>

And here are my explanations on how and why this works.

Why didn't android:dropDownSelector work ?

It all comes down to what happen when we click on the Spinner. Once clicked, it will go through a process to create a DropDownListView.

During its creation, it will use the build-in attribute R.attr.dropDownListViewStyle to create AbsListView.

Then, the AbsListView will extract the drawable from R.styleable.AbsListView_listSelector attr, which will become the selector:

final Drawable selector = a.getDrawable(R.styleable.AbsListView_listSelector);
if (selector != null) {
    setSelector(selector);
}

As a result, the android:dropDownSelector that we gave it to Spinner does not have any effects on the AbsListView that is created for popup.

That's why in order to actually set the selector, we need to change the android:listSelector from the Theme.

Why use android:Widget.ListView as the parent of the theme ?

If we look into our application theme, we should find something like this :

<style name="{THEME_NAME}" parent="{PARENT_THEME}">
    <item name="dropDownListViewStyle">?android:attr/dropDownListViewStyle</item>
    <item name="android:dropDownListViewStyle">@style/Widget.AppCompat.ListView.DropDown</item>
</style>

In my case, dropDownListViewStyle by default is @style/Widget.AppCompat.ListView.DropDown, which is inherited from android:Widget.ListView :

<style name="Base.Widget.AppCompat.ListView" parent="android:Widget.ListView">
    <item name="android:listSelector">?attr/listChoiceBackgroundIndicator</item>
</style>

So just not to mess up other settings, I decided to use android:Widget.ListView as the parent and change the property of android:listSelector.

Gervais answered 3/11, 2023 at 7:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.