Wednesday, March 25, 2015

How to use Spinner in Android

Android Spinner
In Android, Spinner is a single selection drop down list. Spinner give us an easy way to select one value/item from a list. As asp.net DropDownList, Spinner shows its currently selected value. When app user touch a Spinner object, it display a drop down menu which contains all available values. So, after touching the Spinner object and expand dropdown menu, users can change their selection from Spinner items collection.

Android developers can draw a Spinner object in app user interface by two ways. Developers can place a <Spinner> object in XML layout or they can declare/initialize Spinner widget in java code (Activity or Fragment source code) programmatically. When place a Spinner object in XML layout file, developers can manage better to display it in user interface.

Android developers allowed to populate a Spinner widget with values from various data sources. But each data source must be provided through a SpinnerAdapter.

SpinnerAdapter extended Adapter that is the bridge between a Spinner object and its data. SpinnerAdapter define two different views, one view shows the data in Spinner itself and another view shows the data in drop down list when Spinner is expanded.



We can populate a Spinner object from an Array. We need to initialize an ArrayAdapter to generate a Spinner values from an Array. A CursorAdapter also help us to data bind a Spinner widget with database data (such as SQLite Database Query Data).

ArrayAdapter is a concrete BaseAdapter that is backed by an array of arbitrary objects.

When a Spinner data is pre-determined, then we can put those data in a String Array which is defined in String resource file. We can put a String Array in res/values folder, such as if we want to put a String Array file named colors-array.xml then our String Array file's path will be res/values/colors-array.xml. So, later we can reference this array in our application.

We can reference a String Array using the value provided in the 'name' attribute not the name of XML file. So, if our String Array name is array-of-colors then we can reference it in our source code (Activity or Fragment) as R.array.array-of-colors.

In the first example code, we demonstrate how can we populate a Spinner object with data from String Array XML file. This example describe to grab external resource and populate Spinner values.

ArrayAdpater<CharSequence>createFromResource(Context context, int textArrayResId, int textViewResId) method allow us to create a new ArrayAdapter from external resources. Simply, createFromResource() method provide a way to create an ArrayAdapter from the String Array which Array defined in a String Array XML file. The third argument named 'textViewResId' is a layout resource that define how the values appears in the Spinner widget.

In this example, we uses 'simple_spinner_item' layout that is default and provided by the Android platform. Android developers can use their own layout to define Spinner's values appearance.

Next, we need to call the ArrayAdapter.setDropDownViewResource() method to specify the layout resource to create the drop down views for Spinner widget. In this example, we uses 'simple_spinner_drop_down_item' layout and it is Android platform defined standard layout.

Now, we will describe, What happen when app users select an item/option from Spinner object or users expand Spinner object and leave it without changing current selection. Yes, when an app user select a value from Spinner's generated drop down menu, the Spinner object receive an on-item-selected event.



We can define a selection event handler for Spinner object implementing the AdapterView.OnItemSelectedListener interface. This listener has two corresponded callback methods, those are onItemSelected() callback method and onNothingSelected() callback method.

onItemSelected() callback method invoked when user select an item from the Spinner object. onNothingSelected() callback method invoked when selection disappears from this view. The selection can disappear when the Adapter becomes empty.

1. Spinner Example

activity_spinner_example.xml

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context="com.cfsuman.me.androidexamples.SpinnerExample"
    >
    <!--display a spinner on user interface-->
    <Spinner
        android:id="@+id/spinner"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
</RelativeLayout>
res/values/string_array_colors.xml

<?xml version="1.0" encoding="utf-8" ?>
<resources>
    <string-array name="colors_array">
        <item>Red</item>
        <item>Green</item>
        <item>Blue</item>
        <item>Yellow</item>
        <item>Magenta</item>
        <item>Maroon</item>
    </string-array>
</resources>
SpinnerExample.java

package com.cfsuman.me.androidexamples;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
//import the Spinner class
import android.widget.Spinner;
//import the ArrayAdapter class
import android.widget.ArrayAdapter;
import android.widget.AdapterView;
import android.view.View;
import android.widget.Toast;


public class SpinnerExample extends ActionBarActivity {

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

        //.................populate a spinner............
        final Spinner spinner = (Spinner) findViewById(R.id.spinner);
        //Create an ArrayAdapter by using a string array and a default spinner layout
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,R.array.colors_array, android.R.layout.simple_spinner_item);
        //Specify the layout to use when the list of choices appear
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        //Now apply the adapter to spinner
        spinner.setAdapter(adapter);

        //............spinner item selected listener........
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){

            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int pos, long id){
                //We are here that means an item was selected
                //Now we retrieve the user selection
                //Get the selected item text
                String selectedItemText = parent.getItemAtPosition(pos).toString();
                Toast toastSpinnerSelection = Toast.makeText(getApplicationContext(), selectedItemText, Toast.LENGTH_SHORT);
                //display the toast notification on user interface
                //set the toast display location
                toastSpinnerSelection.setGravity(Gravity.LEFT|Gravity.BOTTOM,20,150);
                toastSpinnerSelection.show();
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent){
                //Another interface callback
            }

        });
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}


2. Populate Spinner from ArrayList

This is the second example of Spinner object. Here we will see, how can we populate a Spinner object from an Array values. This array and its contents initialized in java source code. In the last example, we saw that we call external resource file to get Array object and populate Spinner with data. In this example code, we will not depend on res/values/example-string-array.xml file's contain Array, instead we initialize a new Array object in Activity or Fragment source code and populate the Array with items. At last, we populate Spinner widget with values from newly created Array object.

First, we create an Array object then we create an ArrayList object and populate it by Array values. Here, we uses Arrays.asList() method to populate an ArrayList with Array values. Next, we create an ArrayAdapter by using the ArrayList object. Next, we databind Spinner object with ArrayAdapter and populate Spinner widget with values.

In this second example code, we generate two Spinner object. First Spinner object uses the android:spinnerMode attribute value to 'dropdown' and second Spinner element uses the android:spinnerMode attribute value to 'dialog'.

android:spinnerMode attribute value 'dropdown' allow us to present Spinner options as an inline dropdown anchored to the Spinner widget itself. And Spinner mode 'dialog' define Spinner options will be presented in the app interface as a dialog window.
activity_spinner_array_list.xml

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="com.cfsuman.me.myapplication5.SpinnerArrayList"
    >
    <Spinner
        android:id="@+id/spinner"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:spinnerMode="dropdown"
        />
    <Spinner
        android:id="@+id/spinner2"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:spinnerMode="dialog"
        android:layout_toRightOf="@id/spinner"
        />
</RelativeLayout>
SpinnerArrayList.java

package com.cfsuman.me.myapplication5;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
//additional imported classes
import android.widget.Spinner;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import android.widget.ArrayAdapter;


public class SpinnerArrayList extends ActionBarActivity {

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

        //......define spinner in java code...........
        Spinner spinner = (Spinner) findViewById(R.id.spinner);
        Spinner spinner2 = (Spinner) findViewById(R.id.spinner2);
        //Initialize a string array
        String[] redColorsArray = new String[]{"Red","IndianRed","Crimson","DarkRed","Pink"};
        //populate an arraylist with array values
        List<String> redColorsList = new ArrayList<String>(Arrays.asList(redColorsArray));
        //Create a ArrayAdapter using arraylist and a default spinner layout
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item,redColorsList);
        //specify the layout to appear list items
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        //data bind adapter with both spinners
        spinner.setAdapter(adapter);
        spinner2.setAdapter(adapter);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}


More android examples