Hi there, in this Android Spinner with Search Example you will learn how to use xml spinner with a search option. As soon as the spinner’s down arrow would be tapped, a searchbar followed by a  list  of  options would pop up. The list will eventually get filtered as you type something into the search bar. The sample output of this Android Spinner with Search can be seen below.

Android Spinner with Search Example
Creating a New Android Studio Project
- Create a new Android Studio Project with Empty Activity.
- As usual, we shall begin with configuring the MainActivity.java and activity_main.xml. Add the following codes into respective files.
- Here’s the activity_main.xml. It consists of the xml code of the Searchbar.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <?xml version="1.0" encoding="utf-8"?> <RelativeLayout     xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:app="http://schemas.android.com/apk/res-auto"     xmlns:tools="http://schemas.android.com/tools"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:paddingBottom="@dimen/activity_vertical_margin"     android:paddingLeft="@dimen/activity_horizontal_margin"     android:paddingRight="@dimen/activity_horizontal_margin"     android:paddingTop="@dimen/activity_vertical_margin"     tools:context="com.example.manishvishwakarma.searchablespinnermine.MainActivity">     <com.example.manishvishwakarma.searchablespinnermine.SearchableSpinner         android:id="@+id/spinner"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:entries="@array/colleges"         app:hintText="Name your college with State"/> </RelativeLayout> | 
- We needn’t configure the MainActivity.java in this project. Instead, we’ll be creating a two classes named SearchableSpinner.java and SearchableListDialog.java. So, go ahead and create a class named SearchableSpinner.java and the following code. In this class, there’s a string called selectedItem which contains the value of the selected item in the searchlist. You can use it as per required.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | package com.example.manishvishwakarma.searchablespinnermine; import android.app.Activity; import android.content.Context; import android.content.ContextWrapper; import android.content.DialogInterface; import android.content.res.TypedArray; import android.text.TextUtils; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.widget.ArrayAdapter; import android.widget.Spinner; import android.widget.SpinnerAdapter; import android.widget.Toast; import com.example.manishvishwakarma.searchablespinnermine.R; import com.example.manishvishwakarma.searchablespinnermine.SearchableListDialog; import java.util.ArrayList; import java.util.List; public class SearchableSpinner extends Spinner implements View.OnTouchListener,         SearchableListDialog.SearchableItem {     String selectedItem;     //this string above will store the value of selected item.     public static final int NO_ITEM_SELECTED = -1;     private Context _context;     private List _items;     private SearchableListDialog _searchableListDialog;     private boolean _isDirty;     private ArrayAdapter _arrayAdapter;     private String _strHintText;     private boolean _isFromInit;     public SearchableSpinner(Context context) {         super(context);         this._context = context;         init();     }     public SearchableSpinner(Context context, AttributeSet attrs) {         super(context, attrs);         this._context = context;         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SearchableSpinner);         final int N = a.getIndexCount();         for (int i = 0; i < N; ++i) {             int attr = a.getIndex(i);             if (attr == R.styleable.SearchableSpinner_hintText) {                 _strHintText = a.getString(attr);             }         }         a.recycle();         init();     }     public SearchableSpinner(Context context, AttributeSet attrs, int defStyleAttr) {         super(context, attrs, defStyleAttr);         this._context = context;         init();     }     private void init() {         _items = new ArrayList();         _searchableListDialog = SearchableListDialog.newInstance                 (_items);         _searchableListDialog.setOnSearchableItemClickListener(this);         setOnTouchListener(this);         _arrayAdapter = (ArrayAdapter) getAdapter();         if (!TextUtils.isEmpty(_strHintText)) {             ArrayAdapter arrayAdapter = new ArrayAdapter(_context, android.R.layout                     .simple_list_item_1, new String[]{_strHintText});             _isFromInit = true;             setAdapter(arrayAdapter);         }     }     @Override     public boolean onTouch(View v, MotionEvent event) {         if (event.getAction() == MotionEvent.ACTION_UP) {             if (null != _arrayAdapter) {                 // Refresh content #6                 // Change Start                 // Description: The items were only set initially, not reloading the data in the                 // spinner every time it is loaded with items in the adapter.                 _items.clear();                 for (int i = 0; i < _arrayAdapter.getCount(); i++) {                     _items.add(_arrayAdapter.getItem(i));                 }                 // Change end.                 _searchableListDialog.show(scanForActivity(_context).getFragmentManager(), "TAG");             }         }         return true;     }     @Override     public void setAdapter(SpinnerAdapter adapter) {         if (!_isFromInit) {             _arrayAdapter = (ArrayAdapter) adapter;             if (!TextUtils.isEmpty(_strHintText) && !_isDirty) {                 ArrayAdapter arrayAdapter = new ArrayAdapter(_context, android.R.layout                         .simple_list_item_1, new String[]{_strHintText});                 super.setAdapter(arrayAdapter);             } else {                 super.setAdapter(adapter);             }         } else {             _isFromInit = false;             super.setAdapter(adapter);         }     }     //The method just below is executed  when an item in the searchlist is tapped.This is where we store the value int string called selectedItem.      @Override     public void onSearchableItemClicked(Object item, int position) {         setSelection(_items.indexOf(item));         if (!_isDirty) {             _isDirty = true;             setAdapter(_arrayAdapter);             setSelection(_items.indexOf(item));         }         selectedItem= getItemAtPosition(position).toString();         Toast.makeText(getContext(),"You selected "+selectedItem,Toast.LENGTH_LONG).show();     }     private Activity scanForActivity(Context cont) {         if (cont == null)             return null;         else if (cont instanceof Activity)             return (Activity) cont;         else if (cont instanceof ContextWrapper)             return scanForActivity(((ContextWrapper) cont).getBaseContext());         return null;     }     @Override     public int getSelectedItemPosition() {         if (!TextUtils.isEmpty(_strHintText) && !_isDirty) {             return NO_ITEM_SELECTED;         } else {             return super.getSelectedItemPosition();         }     }     @Override     public Object getSelectedItem() {         if (!TextUtils.isEmpty(_strHintText) && !_isDirty) {             return null;         } else {             return super.getSelectedItem();         }     } } | 
- Next, create a class named SearchableListDialog.java and add the following code.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | package com.example.manishvishwakarma.searchablespinnermine; import android.app.AlertDialog; import android.app.Dialog; import android.app.DialogFragment; import android.app.SearchManager; import android.content.Context; import android.content.DialogInterface; import android.os.Bundle; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.SearchView; import java.io.Serializable; import java.util.List; public class SearchableListDialog extends DialogFragment implements         SearchView.OnQueryTextListener, SearchView.OnCloseListener {     private static final String ITEMS = "items";     private ArrayAdapter listAdapter;     private ListView _listViewItems;     private SearchableItem _searchableItem;     private OnSearchTextChanged _onSearchTextChanged;     private SearchView _searchView;     private String _strTitle;     private String _strPositiveButtonText;     private DialogInterface.OnClickListener _onClickListener;     public SearchableListDialog() {     }     public static SearchableListDialog newInstance(List items) {         SearchableListDialog multiSelectExpandableFragment = new                 SearchableListDialog();         Bundle args = new Bundle();         args.putSerializable(ITEMS, (Serializable) items);         multiSelectExpandableFragment.setArguments(args);         return multiSelectExpandableFragment;     }     @Override     public void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);     }     @Override     public View onCreateView(LayoutInflater inflater, ViewGroup container,                              Bundle savedInstanceState) {         getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams                 .SOFT_INPUT_STATE_HIDDEN);         return super.onCreateView(inflater, container, savedInstanceState);     }     @Override     public Dialog onCreateDialog(Bundle savedInstanceState) {         // Getting the layout inflater to inflate the view in an alert dialog.         LayoutInflater inflater = LayoutInflater.from(getActivity());         // Crash on orientation change #7         // Change Start         // Description: As the instance was re initializing to null on rotating the device,         // getting the instance from the saved instance         if (null != savedInstanceState) {             _searchableItem = (SearchableItem) savedInstanceState.getSerializable("item");         }         // Change End         View rootView = inflater.inflate(R.layout.searchable_list_dialog, null);         setData(rootView);         AlertDialog.Builder alertDialog = new AlertDialog.Builder(getActivity());         alertDialog.setView(rootView);         String strPositiveButton = _strPositiveButtonText == null ? "CLOSE" : _strPositiveButtonText;         alertDialog.setPositiveButton(strPositiveButton, _onClickListener);         String strTitle = _strTitle == null ? "Select Item" : _strTitle;         alertDialog.setTitle(strTitle);         final AlertDialog dialog = alertDialog.create();         dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams                 .SOFT_INPUT_STATE_HIDDEN);         return dialog;     }     // Crash on orientation change #7     // Change Start     // Description: Saving the instance of searchable item instance.     @Override     public void onSaveInstanceState(Bundle outState) {         outState.putSerializable("item", _searchableItem);         super.onSaveInstanceState(outState);     }     // Change End     public void setTitle(String strTitle) {         _strTitle = strTitle;     }     public void setPositiveButton(String strPositiveButtonText) {         _strPositiveButtonText = strPositiveButtonText;     }     public void setPositiveButton(String strPositiveButtonText, DialogInterface.OnClickListener onClickListener) {         _strPositiveButtonText = strPositiveButtonText;         _onClickListener = onClickListener;     }     public void setOnSearchableItemClickListener(SearchableItem searchableItem) {         this._searchableItem = searchableItem;     }     public void setOnSearchTextChangedListener(OnSearchTextChanged onSearchTextChanged) {         this._onSearchTextChanged = onSearchTextChanged;     }     private void setData(View rootView) {         SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context                 .SEARCH_SERVICE);         _searchView = (SearchView) rootView.findViewById(R.id.search);         _searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName                 ()));         _searchView.setIconifiedByDefault(false);         _searchView.setOnQueryTextListener(this);         _searchView.setOnCloseListener(this);         _searchView.clearFocus();         InputMethodManager mgr = (InputMethodManager) getActivity().getSystemService(Context                 .INPUT_METHOD_SERVICE);         mgr.hideSoftInputFromWindow(_searchView.getWindowToken(), 0);         List items = (List) getArguments().getSerializable(ITEMS);         _listViewItems = (ListView) rootView.findViewById(R.id.listItems);         //create the adapter by passing your ArrayList data         listAdapter = new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1,items);        //attach the adapter to the list         _listViewItems.setAdapter(listAdapter);         _listViewItems.setTextFilterEnabled(true);         _listViewItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {             @Override             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {                 _searchableItem.onSearchableItemClicked(listAdapter.getItem(position), position);                 getDialog().dismiss();             }         });     }     @Override     public boolean onClose() {         return false;     }     @Override     public boolean onQueryTextSubmit(String s) {         _searchView.clearFocus();         return true;     }     @Override     public boolean onQueryTextChange(String s) { //        listAdapter.filterData(s);         if (TextUtils.isEmpty(s)) { //                _listViewItems.clearTextFilter();             ((ArrayAdapter) _listViewItems.getAdapter()).getFilter().filter(null);         } else {             ((ArrayAdapter) _listViewItems.getAdapter()).getFilter().filter(s);         }         if (null != _onSearchTextChanged) {             _onSearchTextChanged.onSearchTextChanged(s);         }         return true;     }     public interface SearchableItem<T> extends Serializable {         void onSearchableItemClicked(T item, int position);     }     public interface OnSearchTextChanged {         void onSearchTextChanged(String strText);     } } | 
- By now, we are done with the Java part. Now, we have some business  left with xml resource files. So, let’s deal with it.
- Create a layout resource file named  searchable_list_dialog.xml and add the following code. It configures the view after spinner is tapped.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <?xml version="1.0" encoding="UTF-8"?> <LinearLayout     xmlns:android="http://schemas.android.com/apk/res/android"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:orientation="vertical"     android:paddingTop="8dp"     android:paddingRight="8dp"     android:paddingLeft="8dp">     <SearchView         android:id="@+id/search"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:iconifiedByDefault="false"/>     <ListView         android:id="@+id/listItems"         android:layout_width="match_parent"         android:layout_height="wrap_content"/> </LinearLayout> | 
- Next, create a values resource file named colleges.xml and add the following code. It will contain the list of options to be filtered upon the search.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <resources>     <string name="app_name">Spinner with Search</string>     <string-array name="colleges">     //Arts and Science Colleges         <item>Mahatma Gandhi Government College,Andaman and Nicobar Islands</item>         <item>Tagore Government College of Education,Andaman and Nicobar Islands</item>         <item>Dr B R Ambedkar Institute of Technology Port Blair,Andaman and Nicobar Islands</item>         <item>Government Arts College, Rajahmundry,Andhra Pradesh</item>         <item>Government Medical College, Anantapur,Andhra Pradesh</item>         <item>Maharajah\'s Government College of Music and Dance,Andhra Pradesh</item>         <item>P. V. K. N. Government College,Andhra Pradesh</item>         <item>Silver Jubilee Government Degree College,Andhra Pradesh</item>     </string-array> </resources> | 
- Finally, create a values resource file named attrs.xml and add the following code.
| 1 2 3 4 5 6 7 8 | <?xml version="1.0" encoding="utf-8"?> <resources>     <declare-styleable name="SearchableSpinner">         <attr name="hintText" format="string"/>     </declare-styleable> </resources> | 
- That’all. Run the app and you will find a spinner. As you tap it, it shall turn into a search bar. If you still find some problem, let me know in the comments section or you can also go through the source code of this Android Spinner with Search Example.
[sociallocker id=1372] Android Spinner with Search Example [/sociallocker]
So thats all for this Android Spinner with Search Example. Stay tuned for more android tutorials. Thank You 🙂
 



