Creating a text filter (like quick search) for a Spinner in Android

22,840

Solution 1

Looks like you are talking about similar functionality given in AutoCompleteTextView

Solution 2

I know this question is old, but today i also needed this function, and because I wasn´t able to find anything, i made myself a adapter for those spinner

The Adapter:

public class Searchspinner extends ArrayAdapter<String> {
    private LayoutInflater inflater;
    private boolean dropdown = false;
    private OnClickListener onsearch;
    private ActionBar ab;
    private final ArrayList<String> result = new ArrayList<String>();
    private InputMethodManager keyboard;
    private boolean searching = false;
    public Searchspinner(Context context, int resource,
            ArrayList<String> objects, LayoutInflater l, ActionBar a,
            InputMethodManager imm, String spinnerid) {
        super(context, resource, objects);
        inflater = l;
        ab = a;
        keyboard = imm; 
        createSearch();
        // TODO Auto-generated constructor stub
    }
    @Override
    public View getDropDownView(int position, View cnvtView, ViewGroup prnt{
        dropdown = true;
        return getCustomView(position, cnvtView, prnt);
    }
    @Override
    public View getView(int pos, View cnvtView, ViewGroup prnt) {
        dropdown = false;
        return getCustomView(pos, cnvtView, prnt);
    }
    public View getCustomView(int position, View convertView, ViewGroup     parent) {
        if (!dropdown) {
            View mySpinner = inflater.inflate(
                    R.layout.spinner_ressource_search, parent, false);
            TextView main_text = (TextView) mySpinner
                    .findViewById(R.id.tv_spinner_first);
            main_text.setText(getItem(position));
            ImageButton search = (ImageButton) mySpinner
                    .findViewById(R.id.searchbutton);
            if (!searching) {
                search.setImageResource(R.drawable.search);
            } else {
                search.setImageResource(R.drawable.search_check);
            }
            search.setOnClickListener(onsearch);
            return mySpinner;
        }
        View mySpinner = inflater.inflate(R.layout.auftragtextview, parent,
                false);
        TextView sub_text = (TextView)  mySpinner.findViewById(R.id.TextView01);
        sub_text.setText(getItem(position));
        return mySpinner;
    }
    private void createSearch() {
        onsearch = new OnClickListener() {
            @Override
            public void onClick(View v) {       
                // TODO Auto-generated method stub
                if (searching) {
                    searching = false;
                    ab.setCustomView(R.layout.actionbar_layout);
                    ab.getCustomView().setTag("0");
                    keyboard.toggleSoftInput(0,
                            InputMethodManager.HIDE_IMPLICIT_ONLY);
                    for (int i = 0; i < result.size(); i++) {
                        add(result.get(i));
                        result.remove(i);
                        i--;
                    }
                    ((ImageButton)  v).setImageResource(R.drawable.search);
                    return;
                }
                ((ImageButton)  v).setImageResouce(R.drawable.search_check);
                searching = true;
                ab.setCustomView(R.layout.searchable);
                final EditText et = (EditText) ab.getCustomView()
                        .findViewById(R.id.editText1);
                et.setActivated(true);
                    keyboard.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT,
                        0);
                et.requestFocus();
                et.addTextChangedListener(new TextWatcher() {
                    @Override
                    public void onTextChanged(CharSequence s, int start,
                            int before, int count) {
                        for (int i = 0; i < getCount(); i++) {
                            if (!getItem(i).contains(s)) {
                                result.add(getItem(i));
                                remove(getItem(i));
                                i--;
                            }
                        }
                        for (int i = 0; i < result.size(); i++) {
                            if (result.get(i).toLowerCase()
                                        .contains(s.toString().toLowerCase())) {
                                add(result.get(i));
                                result.remove(i);
                                i--;
                            }
                        }
                    }
                    @Override
                    public void beforeTextChanged(CharSequence s,
                            int start, int count, int after) {
                        // TODO Auto-generated method stub
                    }
                    @Override
                    public void afterTextChanged(Editable s) {
                        // TODO Auto-generated method stub
                    }
                });
            }
        };
    }
}

The spinner_ressource_search.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >

<TextView
    android:id="@+id/tv_spinner_first"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:text="TextView" />

<ImageButton
    android:id="@+id/searchbutton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_alignParentTop="true"
    android:background="@android:color/transparent"
    android:src="@drawable/search" />

</RelativeLayout>

and the auftragtextview.xml:

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/TextView01"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:text="@+d/TextView01"
    android:textSize="16sp" >
</TextView>

and this is how you create the Adapter:

Searchspinner auftragSpinnerAdapter = new Searchspinner(
    this.getApplicationContext(),
    R.layout.auftragtextview,
    list_auftragSpinner,getLayoutInflater(),
    getActionBar(),
    (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE)
);  

I hope this is going to help anybody, and that i haven´t missed a already build in way to do this :D
Greetings

Edit:

The searcheble.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:background="@drawable/actionbar_background_beosys" >
<EditText
    android:id="@+id/editText1"
    android:hint="@string/suche"
    android:layout_width="fill_parent"
    android:layout_height="40dp"
    android:layout_marginLeft="15dp"
    android:paddingLeft="15dp"
    android:paddingRight="15dp"
    android:layout_marginRight="15dp"
    android:singleLine="true"
  /> 

So the EditText1 is just a simple editText in The View that get´s in the Actionbar when you search.

The ActionbarLayout is the normal ActionbarView.

Solution 3

You can implement it by your self.

Use a button instead of spinner, design a dialog with an EditText for query input and a ListView for content of you want to display. Then filter the content of ListView according to what user is entered in EditText.

filter(list, text);
adapter.notifyDataSetChanged(); 
Share:
22,840
Adam Arold
Author by

Adam Arold

I do programming for a living. I like tinkering with stuff from bare metal to designing architectures. I also contribute to the Open Source community. Currently I'm based on the JVM (Kotlin/Clojure/Java) but I'm still looking for an Elixir (pun intended). Currently I'm hacking simulation-based games and world/flora/fauna/civilization generation (Dwarf Fortress style). If you think we can work together (programming/pixel art) drop me a mail. Check out my Hexagonal Grid library if interested: Hexameter If you need a multiplatform messaging bus: Riptide or a multiplatform terminal emulator for games: Zircon You can find my LinkedIn profile here I also created the unicorns tag on meta and #SOreadytohelp.

Updated on July 09, 2022

Comments

  • Adam Arold
    Adam Arold almost 2 years

    I'm developing an Android application. I have my activity here with some widgets including a Spinner. I want that Spinner object to be searchable using the quick search button. The idea is that the user tapped the Spinner object and he sees the list (the adapter). If he taps the quick search button he should be provided with a text field to enter a letter and then the spinner list jumps to the fist word it finds with the letter supplied. Just as it works with html and select tags.

    I tried google (and SO of course) but it seems that

    • no one is interested in a solution like this or
    • it is a closely guarded secret. :)

    Do you have some pointers in this topic?

  • Adam Arold
    Adam Arold about 13 years
    Well, the application is using a special Spinner object (extended from Spinner) which has key-value pairs. In addition it must be a dropdown not an edit text field. I don't think that it would work this way.
  • Aritz
    Aritz over 9 years
    @AdamArold so how could this be the accepted answer? Spinners allow selection even though no input value introduced.
  • Adam Arold
    Adam Arold over 9 years
    As you can see this question is 3 years old. I don't use Android for like 1 year so it is not relevant anymore.
  • ShahiM
    ShahiM almost 9 years
    what are the searchable, actionbar_layout and editText1 items??
  • Juliatzin
    Juliatzin over 8 years
    actionbar_layout is still not defined in the answer
  • Gabriel
    Gabriel almost 7 years
    That's a really nice solution! No need for 3rd library