Spinner
provides a quick way to select one value from a set of options (like select
dropdowns in HTML).
Some important properties of spinner are:
android:prompt
. The prompt to display when the spinner’s dialog is shown.android:spinnerMode
. It defines display mode for spinner options. This property has two options: Dialog
mode and DropDown
mode. Dialog
mode uses a dialog window for selecting spinner options and DropDown
mode uses drop-down anchored to the Spinner
for selecting spinner options.android:entries
. It references to an array resource that will populate the Spinner
. Create a spinner like any view and specify the android:entries
attribute to specify the set of options:
<Spinner android:id="@+id/spinner" android:layout_width="wrap_content" android:entries="@array/planets_arrays" android:prompt="@string/planets_prompt" android:layout_height="wrap_content" />
Get the selected item out a spinner using:
Spinner spinner = (Spinner) findViewById(R.id.spinner); String value = spinner.getSelectedItem().toString();
The data used to populate the Spinner
can come from various sources but must be provided through a SpinnerAdapter
like an ArrayAdapter
if the source is an array or a CursorAdapter
for result sets from database queries. ArrayAdapter
and CursorAdapter
(or SimpleCursorAdapter
) are indirect sub classes of SpinnerAdapter
.
String Array Resource
Specify the string array of options in res/values/planets_array.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="planets_array"> <item>Mercury</item> <item>Venus</item> <item>Earth</item> <item>Mars</item> </string-array> </resources>
You can also load a spinner using an adapter for a dynamic source of options using an Adapter
:
Spinner spinner = (Spinner) findViewById(R.id.spinner); // create an ArrayAdapter using the string array and a default spinner layout ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.planets_array, android.R.layout.simple_spinner_item); // specify the layout to use when the list of choices appears adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); // apply the adapter to the spinner spinner.setAdapter(adapter);
The createFromResource
method allows us to create an ArrayAdapter
from the string array resource. The third layout argument passed to the constructor call is basically how the spinner control will look like when a manual selection is made (or the default one is showing up). The setDropDownViewResource
method is used to specify the layout file used to represent each item in the dropdown. We use the in-built simple_spinner_dropdown_item
layout file provided by the android platform.
ArrayList or Array of Objects Resource
We could pass on the data via an ArrayList
or an array of objects (for example strings). Let’s see an example with ArrayList
:
ArrayList<String> planets = new ArrayList<String>(); planets.add("Mercury"); planets.add("Venus"); planets.add("Earth"); planets.add("Mars"); ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, planets); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinner.setAdapter(adapter);
SQLite Resource
Displaying the contents of a Cursor
in a Spinner
is pretty straightforward.
First, we perform a query as discussed here, fetching just the Movie title and id (queryCols
). Next, we create a SimpleCursorAdapter
instance passing it the Cursor
, an array of columns to display (adapterCols
), and an array of views that the columns should be displayed in (adapterRowViews
). Then, we set the Spinner
’s Adapter to the `SimpleCursorAdapter
.
String[] queryCols = new String[]{MovieDBHelper.ID, MovieDBHelper.TITLE}; SQLiteDatabase db = new MovieDBHelper(this).getReadableDatabase(); Cursor cursor = db.query( MovieDBHelper.TABLE_NAME, // the table to query queryCols, // the columns to return null, // the columns for the WHERE clause null, // the values for the WHERE clause null, // don't group the rows null, // don't filter by row groups null // don't sort ); String[] adapterCols = new String[]{MovieDBHelper.TITLE}; int[] adapterRowViews = new int[]{android.R.id.text1}; SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter( this, android.R.layout.simple_spinner_item, cursor, adapterCols, adapterRowViews, 0); cursorAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinner.setAdapter(cursorAdapter);
Custom Spinner dropdown example
For customization we need to create a custom adapter class and then extends our default adapter in that class.
Add spinner with custom background in your layout file
<Spinner android:background="@drawable/custom_spinner_background" android:spinnerMode="dropdown" android:id="@+id/spinner" android:layout_width="fill_parent" android:layout_height="wrap_content" />
Add following code to res/drawable/custom_spinner_background* as background for Spinner
<?xml version="1.0" encoding="UTF-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="@android:color/white"/> <corners android:radius="4dp"></corners> <stroke android:color="#cccccc" android:width="1dp"/> </shape>
Initialize custom Spinner
and set custom adapter with planets list
Spinner spinner = (Spinner) findViewById(R.id.spinner); String[] arPlanets = getResources().getStringArray(R.array.planets_array); ArrayListplanets = new ArrayList (Arrays.asList(arPlanets)); CustomSpinnerAdapter customSpinnerAdapter=new CustomSpinnerAdapter(ServiceActivity.this, planets); spinner.setAdapter(customSpinnerAdapter);
Custom Spinner
adapter code
public class CustomSpinnerAdapter extends BaseAdapter implements SpinnerAdapter { private final Context ctx; private ArrayList<String> items; public CustomSpinnerAdapter(Context ctx, ArrayList<String> items) { this.items = items; this.ctx = ctx; } public int getCount() { return items.size(); } public Object getItem(int i) { return items.get(i); } public long getItemId(int i) { return (long)i; } @Override public View getDropDownView(int position, View convertView, ViewGroup parent) { TextView txt = new TextView(ServiceActivity.this); txt.setPadding(16, 16, 16, 16); txt.setTextSize(18); txt.setGravity(Gravity.CENTER_VERTICAL); txt.setText(items.get(position)); txt.setTextColor(Color.parseColor("#000000")); return txt; } public View getView(int i, View view, ViewGroup viewgroup) { TextView txt = new TextView(ServiceActivity.this); txt.setGravity(Gravity.CENTER); txt.setPadding(16, 16, 16, 16); txt.setTextSize(16); txt.setCompoundDrawablesWithIntrinsicBounds(0, 0, android.R.drawable.arrow_down_float, 0); txt.setText(items.get(i)); txt.setTextColor(Color.parseColor("#000000")); return txt; } }
Result
Useful snippets
Setting spinner item based on value (rather than item position):
public void setSpinnerToValue(Spinner spinner, String value) { int index = 0; SpinnerAdapter adapter = spinner.getAdapter(); for (int i = 0; i < adapter.getCount(); i++) { if (adapter.getItem(i).equals(value)) { index = i; break; } } spinner.setSelection(index); }
Getting the selected value of a Spinner
is really easy. The getSelectedItem()
method on the view object returns the value as an object that can be converted to a string using the toString()
method. So basically we do something like this:
Spinner spPlanet = (Spinner) findViewById(R.id.planets); String planet = spPlanet.getSelectedItem().toString().trim();
Receiving an event when the user selects an item is also very simple. Just need to implement the AdapterView.OnItemSelectedListener
interface with the corresponding onItemSelected
method:
spPlanet.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { String planet = parent.getItemAtPosition(position).toString(); Toast.makeText(MainActivity.this, planet, Toast.LENGTH_SHORT).show(); } @Override public void onNothingSelected(AdapterView<?> parent) {} });