16

I've a Spinner with onItemSelected interation that works, but how the Api specification says:

This callback is invoked only when the newly selected position is different from the previously selected position or if there was no selected item.

I need to remove this limitation and i want that the callback is invoked also if the user select the same element. How to do that? I read a suggestion about extending Spinner class and set the position to INVALID_POSITION, but i've not understood/able to do that. Anyone did the same thing?

user842504
  • 345
  • 3
  • 8

6 Answers6

1

I also needed a solution to this problem. What I wanted to do was have a Spinner that has date ranges with a custom range option. The rows would look something like this:

Apr 10 - May 10
Mar 10 - Apr 10
Feb 10 - Mar 10
Custom Range

The problem is that if the user selects a custom range and then wants to change their custom range, they have to select a different range and then select the custom range option again. I wanted the user to just be able to select "Custom Range" again so that the custom range dialog could be shown again.

I sub-classed Spinner and created my own listener. The code switches the selection, but then immediately switches it so that nothing is selected. In my listener I just ignore any position that is less than zero.

The Spinner just displays the last selected item. I created my own custom adapter and specify what to display for each view, but that shouldn't be necessary. Here is how I sub-classed Spinner.

package com.example.widget;

import android.content.Context;
import android.widget.Spinner;

public class DateRangeSpinner extends Spinner {

private ItemSelectionListener listener;

public DateRangeSpinner(Context context) {
    super(context);
}

/**
 * This listener will be fired every time an item is selected,
 * regardless of whether it has already been selected or not.
 * 
 * @param l
 */
public void setOnItemSelectedListener(ItemSelectionListener l) {
    listener = l;
}

public void removeOnItemSelectedListener() {
    listener = null;
}

@Override
public void setSelection(int position) {
    setSelection(position, true);
}

@Override
public void setSelection(int position, boolean animate) {
    if (listener != null) {
        listener.onItemSelected(position);
    }
    super.setSelection(position, animate);
    super.setSelection(-1, animate);
}   

public interface ItemSelectionListener {
    public void onItemSelected(int position);
}

}

I hope this helps!

TALE
  • 960
  • 13
  • 22
0

why you have select the selected item again. Just give a refresh button if you want to perform that task again.

Suhail Mehta
  • 5,514
  • 2
  • 23
  • 37
  • on my case i prevent that the event it's fired on onCreate method, then my spinner it's setted on the first element. If i need to select it, i can't with this limitation. – jedi Nov 28 '13 at 15:30
0

This is the spinner Element with custom dialog mode and whitout promt:

<Spinner
    android:id="@+id/spinner_metatag"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:entries="@array/search_adv" 
/>

The Array element where the default value is putted at position 0:

<string-array name="search_adv">
    <item>@string/search_adv_prompt</item>
    <item>@string/search_adv_title</item>
    <item>@string/search_adv_desc</item>
    <item>@string/search_adv_autore</item>
    ....
</string-array>

The String elements for the array with the default value:

<string name="search_adv_prompt">Scegli un metatag</string> <!-- Default value-->
<string name="search_adv_title">Titolo</string> 
<string name="search_adv_desc">Descrizione</string> 
<string name="search_adv_autore">Autore</string>
...

And here the code to prevent the event fired on onCreateMethod and the work around to permit to select the same element already selected:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.search_adv_main);

    spinner = (Spinner) findViewById(R.id.spinner_metatag);

    spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
        public void onItemSelected(AdapterView<?> parent, View view, int pos,long id) {
            //prevent onCreate event fire and the loop
            if(pos==0)
                return;

            //HERE YOUR CODE

            //at the end move to the default element the spinner
            spinner.setSelection(0);
        }

        @Override
        public void onNothingSelected(AdapterView<?> arg0) {}
    });
}

Hope helps. The idea come from the second solution from TreKing's answer

jedi
  • 839
  • 12
  • 33
0

You can do this by a custom adapter, like create a layout of your desire views, then inflate this in custom adapter then on onItemClick function you can get the view by this function.

To distinguish each view you must to set the tag of each row.

It probably works in your condition.

Let me know any issue if you have

DEVANG SHARMA
  • 2,662
  • 5
  • 33
  • 52
-1

Use OnItemClickListener instead of on itemSelectedListener.That will work for every click whether it is same or different.

Athul
  • 231
  • 1
  • 7
-2

I guess you must be storing the value in a variable, initialize the vairable with -1. And change the value as the user selects the item spinner, if the value is -1 ask the user to reselect or whatever u want.

@i want that the callback is invoked also if the user select the same element. Android will do it for u as this is the default behavior of android.

Hardik4560
  • 3,202
  • 1
  • 20
  • 31
  • 3
    "Android will do it for u as this is the default behavior of android." That is definitely NOT the default behavior. The default is (oddly), to *NOT* trigger the event at all, when you click on a selection that's already highlighted. – Carol Jan 08 '12 at 03:47