Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set current spinner text without changing associated selection list items

I have a Spinner with some values

| Monday       | 
| Thuesday     |
| Wednesday    |
| Thursday     |
| Friday       |
| Saturday     |
| USER DEFINED |

When the user choose USER DEFINED he can input a custom value in a dialog, assuming that I get this value as String userDef="Your choice".

I need to set this String as current item, without change the spinner selection list, that must appear the same described above, also when the user clicks again on the spinner, something like in Google Analytics Android App, see the image.

unclicked spinner Unclicked spinner Google Analyticsclicked spinner clicked spinner Google Analytics

How could I do this?

like image 316
AndreaF Avatar asked Aug 08 '14 15:08

AndreaF


2 Answers

The key detail for implementing this is that the SpinnerAdapter interface used used by the Spinner has two different but related methods:

  • getView() - creates the view displayed in the Spinner itself.
  • getDropDownView() - creates the view shown in the drop down popup.

Therefore, to have an item that is displayed differently in the popup vs in the spinner itself, you just need to implement these two methods differently. Depending on the specifics of your code the details may vary, but a simple example would be something like:

public class AdapterWithCustomItem extends ArrayAdapter<String>
{
    private final static int POSITION_USER_DEFINED = 6;
    private final static String[] OPTIONS = new String[] {
        "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Custom..." };

    private String mCustomText = "";

    public AdapterWithCustomItem(Context context){
        super(context, android.R.layout.simple_spinner_dropdown_item, OPTIONS);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = super.getView(position, convertView, parent);
        if (position == POSITION_USER_DEFINED) {
            TextView tv = (TextView)view.findViewById(android.R.id.text1);
            tv.setText(mCustomText);
        }

        return view;
    }

    public void setCustomText(String customText) {
        // Call to set the text that must be shown in the spinner for the custom option.
        mCustomText = customText;
        notifyDataSetChanged();
    }

    @Override
    public View getDropDownView(int position, View convertView, ViewGroup parent) {
        // No need for this override, actually. It's just to clarify the difference.
        return super.getDropDownView(position, convertView, parent);
    }
}

Then, when the user enters the custom value, you just need to call the setCustomText() method on the adapter with the text you want to display.

mAdapter.setCustomText("This is displayed for the custom option");

which produces the following result:

enter image description here

Since you are only overriding the getView() method, the drop down still shows the same text as defined in the option itself.

like image 52
matiash Avatar answered Oct 21 '22 20:10

matiash


I think the best way is to implement a custom array adapter. First create a class for each entry:

public class Choice {
    // Represents the underlying value
    public String value;

    // Represents the user-displayed value
    public String text;

    public Choice(String value, String text) {
        this.value = value;
        this.text = text;
    }

    // Only the text will be shown, not the underlying value
    @Override
    public String toString() {
        return text;
    }
}

Then declare your adapter of Choice objects: ArrayAdapter<Choice>. Only the defined text will be shown, and you can access the underlying value whenever an item is selected:

@Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
    int position, long arg3) {
    Choice choice = adapter.get(position);
    // Set the value of the choice, not the text
    myValue = choice.value;
}
like image 26
jlhonora Avatar answered Oct 21 '22 20:10

jlhonora