Android Adventures - Spinners And Pickers
Written by Mike James   
Thursday, 19 September 2013
Article Index
Android Adventures - Spinners And Pickers
Array Adapter
Dynamic change

Working with Android Studio makes building the UI easy with an interactive editor, but you still need to find out how to handle the things it isn't quite so good at. In the next two chapters of our ebook on Android the easy way, we look at spinners and pickers, the next step up from buttons and text controls. 

Android Adventures With Android Studio

Contents

  1. Getting Started With Android Studio
  2. The Activity And The UI
  3. Building The UI and a Calculator App
  4. Lifecycle and State
  5. Basic Controls And Events
  6. Spinners
  7. Pickers
  8. UI Graphics A Deep Dive
  9. ListView And Adapters
  10. Introducing Fragments
  11. Fragments and XML
  12. Fragment And Activity Working Together
  13. Managing Fragments
  14. Custom dialogs using DialogFragment
  15. Dialog Classes In DialogFragment
  16. A NumberPicker DialogFragment Project

Androidgears

 

Spinners are what are referred to as drop down lists or something similar in other UIs. They allow the user to pick from a list of possible items. 

Pickers are similar to spinners in they allow the user to pick an item, but in this case the items are more narrowly defined - a date, a time or a number. Of the pickers the date and time pickers are quite well known but for an odd set of reasons the number picker has long been neglected. 

Let's start with the Spinner.

The Spinner And The ArrayAdapter

The spinner presents a set of alternatives to the user and lets them select one. Putting a Spinner into you project is as easy as using the toolbox in the designer but you can't get away without some Java to make it all work. In particular you need to define the list of items that the Spinner will display when the user activates it. When you first place a Spinner on the design surface it shows some dummy text. Our first task is to replace the dummy text with a real list of alternatives.

 

defaultspinner

 

The simplest sort of thing to show the user is a list of text items and you might well think that the most direct way of doing this is to use a String array - and it is but. In the case of UI widgets that display lists of things Android has a much more general mechanism to cope with the different type of things you could display. Widgets that show lists of things generally work with an example of an "adapter". An adapter basically takes a list of objects and converts them into something that can be displayed in the widget. In general you can create custom Adapters to do clever things with lists of objects of your own so that they display appropriately. In most cases however you can get by with just using the provided built-in adapters. 

In the case of the spinner the most usual choice of adapter is the ArrayAdapter. This takes an array of objects of any type and makes them suitable for display by calling their toString() method. As long as the toString() method produces what you want to see in the Spinner then everything should work. In the case of an array of Strings calling the toString() method on each array element might seem like overkill but it is the price we pay to build mechanisms that can cope with more complicated situations. 

So the plan of action is to create a String array with the items we want to display, use this to initialize an ArrayAdapter object and then attach the ArrayAdapter to the Spinner. 

Creating the array is easy:

String[] country = {"Canada", "Mexico", "USA"};

The ArrayAdapter constructor can seem to be complicated. It seems even more complicated because ArrayAdapter uses generics to allow you to specify the type of each element in the array. If you haven't used generics before, all you need to know is that instead of creating a special array Adapter for each type of array, an IntArrayAdapter, a StringArrayAdapter and so on, you simply have to specify the type as <int> or <String> when you use the ArrayAdapter type. 

For example, to create an ArrayAdapter for an array of Strings you would use:

ArrayAdapter<String> stringArrayAdapter=
  new ArrayAdapter<String>(
         constructor parameters);

The pattern is the same for all the constructors and for different array types. 

There are quite a few ArrayAdapter constructors, but they all need some basic information. They need to know the current context, usually this, the layout to be used to display the list and the array of data items. 

The only difficult one is the layout to be used to display the list. This sounds like a lot of potential hard work until you discover that the system provides some basic standard layouts that you can just use. In our case the layout is:

android.R.layout.simple_spinner_dropdown_item

Notice that this is an integer that determines the layout resource to use. 

Putting all of this together gives:

ArrayAdapter<String> stringArrayAdapter=
 new ArrayAdapter<String>(
  this,
android.R.layout.simple_spinner_dropdown_item,
  country);

And if you are wondering what country is, you have forgotten that we defined a String array called country earlier. 

The final step is to specify the ArrayAdapter to use in the Spinner. First we have to retrieve the Spinner and then we can use its setAdapter methiod:

Spinner spinner=
          (Spinner)findViewById(R.id.spinner);

spinner.setAdapter(stringArrayAdapter);

If you add all of the code to the onCreate event handler the result is:

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

 String[] country={"Canada", "Mexico", "USA"};
 ArrayAdapter<String> stringArrayAdapter=
  new ArrayAdapter<String>(
   this,
 android.R.layout.simple_spinner_dropdown_item,
   country);
 Spinner spinner =
    (Spinner)  findViewById(R.id.spinner);
 spinner.setAdapter(stringArrayAdapter);
}

If you run the program you will see:

spinner1

 

 Handling the selection

The next question is how do you discover that the user has made a selection?

The simple answer is that we have to hookup to the Spinner's events. As always there are three possible ways of doing this -

  • create a sub-class of AdapterView.OnItemSelectedListener and then an instance
  • implement the AdapterView.OnItemSelectedListener interface as part of the activity
  • use an anonymous class

Of the three the anonymous class seems the easiest because Android Studio will generate the interface methods for you. If you start typing the following line and use the autocomplete:

AdapterView.OnItemSelectedListener onSpinner=
     new AdapterView.OnItemSelectedListener(){

then Android Studio will generate:

AdapterView.OnItemSelectedListener onSpinner =
  new AdapterView.OnItemSelectedListener() {
 @Override
 public void onItemSelected(
  AdapterView<?> parent,
  View view,
  int position,
  long id) {
 }
 @Override
 public void onNothingSelected(
  AdapterView<?>  parent) {
 }
}

It also adds an import for AdapterView. You still have to add a semicolon at end, however.

If  you don't use the auto-complete then you might have to type everything in - including the import. 

You can see at once that you have to implement two event handlers:

  • onItemSelected -  triggered when the user selects an item
  • onNothingSelected - triggered when the Spinner has no items or the user deselects all items

You might also wonder what the <?> are in the generated code?

Both events are generic and they work with a range of different types. The <?> is a type wildcard which essentially allows any type to be used. For example List<?> is a list of any type. Of course the actual type isn't known until runtime and so every element of the List is treated as an Object type and its up to you to cast it to something more specific. 

 



Last Updated ( Friday, 17 October 2014 )
 
 

   
Copyright © 2014 i-programmer.info. All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.