Working with Spinners

We have already studied what Spinners are and how they work. So let’s check out the example, learn how we can implement it in our Android App.

we are going to create an application that works with two Spinners, so which are interdependent. The main layout of the application will contain our one TextView and two spinners as its child component views and we need to customize the layout(shown in below image) where one Spinner is placed under the TextView and other spinner is also under the first spinner.

As the options inside the second Spinner will depend on what we select in the first Spinner, thus isVisible initially the second spinner will be hidden and it will only appear when user has selected one option from the spinner.

The second one spinner has the property isVisible which is equals to GONE, which means it exists in the layout but it will not be visible(or it will be hidden).

Hence, in the image below, this looks like it’s not there and you can try and change the value of isVisible to VISIBLE to see if it is there or not. Where then change it back to GONE for now.

The Spinner(classSpinner) holds the list of classes ie. school, which to be selected by the user and based on that choice we will assign the values to the second Spinner(divSpinner) where the user selects an option from the second spinner too and we will create a Toast and display the chosen values on screen.

So let us start, here we have the layout XML file as well as If you want, copy paste the below XML to start with this example in your local machine.

main_activity.xml


<?xml version="1.0" encoding="utf-8"?>
<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">

    <TextView
        android:id="@+id/tvDemo"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:gravity="center"
        android:text="SPINNER DEMO"
        android:layout_alignParentLeft="true" />

    <Spinner
        android:id="@+id/classSpinner"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tvDemo"
        android:layout_marginTop="25dp"
        android:entries="@array/items_class"/>

    <Spinner
        android:id="@+id/divSpinner"
        android:visibility="gone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/classSpinner"
        android:layout_toLeftOf="@id/classSpinner"
        android:layout_marginTop="10dp"
        />

</RelativeLayout>

NOTE: If we are getting an error in this, this is because you have not yet created the below data XML file and once you will create that, the error in this file will be resolved.

As you can see that we have one TextView and two Spinner views inside the xml file along with a few properties specified.

To add items to the Spinner so we can there are two possible ways to provide it with a set of options and One by declaring an array and defining the items in it, But for this example and we will try the other way i.e. using an XML.

You can define a string array in XML like we have shown below in the strings.xml file. In Android as we put the data XML files like our strings.xml file in app → res → values → strings.xml.

strings.xml


<resources>

    <string name="app_name">MyActivity</string>

    <string-array name="items_class">
        <item>Class 1</item>
        <item>Class 2</item>
        <item>Class 3</item>
        <item>Class 4</item>
    </string-array>

    <string-array name="items_div_class_1">
        <item>Div 1-A</item>
        <item>Div 1-B</item>
        <item>Div 1-C</item>
        <item>Div 1-D</item>
    </string-array>

    <string-array name="items_div_class_2">
        <item>Div 2-A</item>
        <item>Div 2-B</item>
        <item>Div 2-C</item>
        <item>Div 2-D</item>
    </string-array>

    <string-array name="items_div_class_3">
        <item>Div 3-A</item>
        <item>Div 3-B</item>
        <item>Div 3-C</item>
        <item>Div 3-D</item>
    </string-array>

    <string-array name="items_div_class_4">
        <item>Div 4-A</item>
        <item>Div 4-B</item>
        <item>Div 4-C</item>
        <item>Div 4-D</item>
    </string-array>

</resources>

Now as we are done with the following things:

  1. We have understood the ui design that we have created in our Android App, which will have 1 TextView and 2 Spinners.
  2. We have defined it in the XML for the User interface.
  3. We have also defined a dataset for the Spinners

In our dataset and string-array named items_class will be assigned to the classSpinner to display the class items in the dropdown list.

To add these data to the spinner all we have to do is add a property android:entries=”@array/items_class” in the main activity layout XML file and by Doing so will assign the values present in the items_class array to classSpinner.

As per the user’s selection of the option from the first spinner and our second Spinner will appear along with options based on the first spinner’s selection, so you will do this through Java code as the user will select from the first picklist at run time i.e. dynamically.

To handle the UI events, we need to implement the code inside the MainActivity.java file and We will start by creating instances of both the spinners and then the assign the setOnItemSelectedListener() on both the spinners.

MainActivity.java


public class MainActivity extends AppCompatActivity 
{
    // these are the global variables
    Spinner classSpinner, divSpinner;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        classSpinner = (Spinner) findViewById(R.id.classSpinner);
        divSpinner = (Spinner) findViewById(R.id.divSpinner);
        
        // Class Spinner implementing onItemSelectedListener
        classSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() 
        {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) 
            {
                // do something upon option selection
            }
        
            @Override
            public void onNothingSelected(AdapterView<?> parent) 
            {
                // can leave this empty
            }
        });
        
        // Div Spinner implementing onItemSelectedListener
        divSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() 
        {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
            {
                // do something upon option selection
            }
        
            @Override
            public void onNothingSelected(AdapterView<?> parent)
            {
                // can leave this empty
            }
        
        });
    }
}

Changing Value of second Spinner based on first Spinner value

Inside the onItemSelected() method of classSpinner and then you have to get the selected item from the dropdown list and based on that value and you have to assign entries i.e. options to divSpinner from the string-array resource, then by adding the following code inside classSpinner’s onItemSelected() method.


classSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() 
{
    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) 
    {
        // Get Selected Class name from the list
        String selectedClass = parent.getItemAtPosition(position).toString();
        switch (selectedClass) 
        {
            case "Class 1":
                // assigning div item list defined in XML to the div Spinner
                divSpinner.setAdapter(new ArrayAdapter<String>(MainActivity.this, 
                                android.R.layout.simple_spinner_dropdown_item, 
                                getResources().getStringArray(R.array.items_div_class_1)));
                break;
    
            case "Class 2":
                divSpinner.setAdapter(new ArrayAdapter<String>(MainActivity.this, 
                                android.R.layout.simple_spinner_dropdown_item, 
                                getResources().getStringArray(R.array.items_div_class_2)));
                break;
    
            case "Class 3":
                divSpinner.setAdapter(new ArrayAdapter<String>(MainActivity.this, 
                                android.R.layout.simple_spinner_dropdown_item, 
                                getResources().getStringArray(R.array.items_div_class_3)));
                break;
    
            case "Class 4":
                divSpinner.setAdapter(new ArrayAdapter<String>(MainActivity.this, 
                                android.R.layout.simple_spinner_dropdown_item, 
                                getResources().getStringArray(R.array.items_div_class_4)));
                break;
        }
        
        //set divSpinner Visibility to Visible
        divSpinner.setVisibility(View.VISIBLE);
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) 
    {
        // can leave this empty
    }
});

You can get the value of the selected class name from the ClassSpinner and For that you have used parent.getItemAtPosition(position).toString() method, so Here, parent is the classSpinner view, and position is the position of the option selected.

Hence in parent.getItemAtPosition(position).toString() you are fetching the item(option) of the classSpinner picklist dropdown present at the position which is stored in the parameter position.

Once you have the name of the class selected in the first dropdown, then we can use a simple switch case to initialize the second dropdown with appropriate set of values.

We will initialize an ArrayAdapter with the respective array of string and will use the adapter to our second spinner divSpinner.

To access the array of string from string resource in XML, we will have to use the method, getResources().getStringArray(ID_OF_ARRAY)

And at the end, you will set the visibility of the second spinner to be VISIBLE.


Creating a Toast to show the selected values

So, when the user selects an option from the second Spinner and then we will create a Toast and display the selected values on screen.


    // getting selected value from second spinner
selectedDiv = parent.getItemAtPosition(position).toString();
// creating Toast
Toast.makeText(MainActivity.this, "\n Class: \t " + selectedClass + "\n Div: \t" + selectedDiv, Toast.LENGTH_LONG).show();

Complete Code for MainActivity.java

Below is the complete code for MainActivity.java

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity 
{
    // these are the global variables
    Spinner classSpinner, divSpinner;
    // string variable to store selected values
    String selectedClass, selectedDiv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        classSpinner = (Spinner) findViewById(R.id.classSpinner);
        divSpinner = (Spinner) findViewById(R.id.divSpinner);
        
        // Class Spinner implementing onItemSelectedListener
        classSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() 
        {
            @Override
            public void onItemSelected(AdapterView parent, View view, int position, long id) 
            {
                String selectedClass = parent.getItemAtPosition(position).toString();
                switch (selectedClass) 
                {
                    case "Class 1":
                        // assigning div item list defined in XML to the div Spinner
                        divSpinner.setAdapter(new ArrayAdapter(MainActivity.this, 
                                        android.R.layout.simple_spinner_dropdown_item, 
                                        getResources().getStringArray(R.array.items_div_class_1)));
                        break;
            
                    case "Class 2":
                        divSpinner.setAdapter(new ArrayAdapter(MainActivity.this, 
                                        android.R.layout.simple_spinner_dropdown_item, 
                                        getResources().getStringArray(R.array.items_div_class_2)));
                        break;
            
                    case "Class 3":
                        divSpinner.setAdapter(new ArrayAdapter(MainActivity.this, 
                                        android.R.layout.simple_spinner_dropdown_item, 
                                        getResources().getStringArray(R.array.items_div_class_3)));
                        break;
            
                    case "Class 4":
                        divSpinner.setAdapter(new ArrayAdapter(MainActivity.this, 
                                        android.R.layout.simple_spinner_dropdown_item, 
                                        getResources().getStringArray(R.array.items_div_class_4)));
                        break;
                }
                
                //set divSpinner Visibility to Visible
                divSpinner.setVisibility(View.VISIBLE);
            }
        
            @Override
            public void onNothingSelected(AdapterView parent) 
            {
                // can leave this empty
            }
        });
        
        // Div Spinner implementing onItemSelectedListener
        divSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() 
        {
            @Override
            public void onItemSelected(AdapterView parent, View view, int position, long id)
            {
                selectedDiv = parent.getItemAtPosition(position).toString();
                /*
                    Now that we have both values, lets create a Toast to
                    show the values on screen
                */
                Toast.makeText(MainActivity.this, "\n Class: \t " + selectedClass +
                                    "\n Div: \t" + selectedDiv, Toast.LENGTH_LONG).show();
            }
        
            @Override
            public void onNothingSelected(AdapterView parent)
            {
                // can leave this empty
            }
        
        });
    }
}

When we run your android application, we will get the first toast message by default because the first item is already assigned to the spinner and don’t worry about it. It’s just go and try to change the spinner selection for class and division dropdowns so you should see the results as below images.

When we select the Class option then as per the class selection your app will load other items in the DivSpinner and we can then select items from the second spinner and when we select an item from the second spinner and your app will display selected items on the device screen.

Subscribe Now