Android:Spinner

From Juneday education
Jump to: navigation, search

Introduction

This chapter will introduce you to .

Videos

Description

Create a Spinner

Using XML

Add the following (inspired from Spinners at the Android Developer site) to the layout where you want the spinner:

<Spinner
    android:id="@+id/band_spinner"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" />

This will add a Spinner to the layout.

Programmatically

Add items/data a Spinner

This is how we want the Spinner to look like after adding a couple of nice Strings to it. Android-Spinner-I.png

Using XML

You can use XML to create the items in the Spinner. Start by creating a String resource, like this:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="great_bands_array">
        <item>Lynyrd Skynyrd</item>
        <item>Allman Brothers</item>
        <item>Jame's gang</item>
    </string-array>
</resources>

Now you can put these values in to your Spinner, typically by writing the following code in the Activity's onCreate method.

  // Find the Spinner
  Spinner spinner = (Spinner) findViewById(R.id.band_spinner);

  // Create an ArrayAdapter using the string array and a default spinner layout
  // there are other ways to create such an adapater and layout, but let's stick to basics
  ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
           R.array.great_bands_array, android.R.layout.simple_spinner_item);

  // Use an Android layout to present the bands
  adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

  // Use the adapter above with the Spinner
  spinner.setAdapter(adapter);

Note: the text above is based on: Spinners at the Android Developer site)

Programmatically

In the example you can download we're getting bands from some kind of storage via a BandStore. We get a BandStore from a factory BandStoreFactory.getBandStore() so the call to get a list of bands would look like this: BandStoreFactory.getBandStore().bands()). We chose this structure since it makes it possible to easily switch to using a BandStore which has a database or "the network" as a backend. Assuming BandStoreFactory.getBandStore().bands()) gives us a list of Bands we can populate the spinner like this. THe code getting the list of bands is highlighted highlighted text.

   Spinner spinner = (Spinner) findViewById(R.id.punk_spinner);
    ArrayAdapter<Band> adapter =
        new ArrayAdapter<Band>(this,
            android.R.layout.simple_spinner_item,
            BandStoreFactory.getBandStore().bands());
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner.setAdapter(adapter);

Note: we use a second spinner (punk_spinner) for this list of bands.

Reacting on user input

We've added a couple of TextViews. These will be upated if the user chooses any of the items in the Spiners. Android-Spinner-II.png

Letting the class extend OnItemSelectedListener

The authors of the books over here at Juneday do not recommend letting the class implement an interface. In our opinion it leads to code where you need to write if statements to check what specific view caused an event. We prefer the two ways below but will show you this one since Android seem to do it a lot.

Let your class implement OnItemSelectedListener

Make your activity implement OnItemSelectedListener by adding implements OnItemSelectedListener

public class MainActivity extends AppCompatActivity implements OnItemSelectedListener {

Implement the interface

Implement the two methods from the interface OnItemSelectedListener :

  public void onItemSelected(AdapterView<?> adapterView, View view, int pos, long l) {
    Log.d(LOG_TAG, "onItemSelected");
    String s = (String) adapterView.getItemAtPosition(pos);
    TextView tv = findViewById(R.id.southern_rock_band_view);
    tv.setText(s);
  }

  @Override
  public void onNothingSelected(AdapterView<?> adapterView) {
  }

The code above sets the text in one of the text views to the band you've chosen.

Create an inner class implementing OnItemSelectedListener

    spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
      @Override
      public void onItemSelected(AdapterView<?> adapterView, View view, int pos, long l) {
        Log.d(LOG_TAG, "onItemSelected");
        Band band = (Band) adapterView.getItemAtPosition(pos);
        TextView tv = findViewById(R.id.punk_band_view);
        tv.setText(band.toString());
      }

      @Override
      public void onNothingSelected(AdapterView<?> adapterView) {
      }
    });

Less code and it's easy to see what code is run if the above spinner is changed. Nice!

Not possible to use lambda

Sorry, this can't be done using lambda since the interface OnItemSelectedListener has two abstract methods:

abstract void	onItemSelected(AdapterView<?> parent, View view, int position, long id);

abstract void	onNothingSelected(AdapterView<?> parent);

Read more about lambda here: Java By Term:Lambda

Classes used

Band

package se.juneday.spinnerexample.domain;

public class Band {

  private String name;

  public Band(String name) {
    this.name = name;
  }

  public String toString() {
    return name;
  }
}

BandStore

package se.juneday.spinnerexample.storage;

import java.util.List;
import se.juneday.spinnerexample.domain.Band;

public interface BandStore {

  List<Band> bands();

}

BandStoreFactory

package se.juneday.spinnerexample.storage;

public class BandStoreFactory {

  public static BandStore getBandStore() {
    return new FakeBandStore();
  }

}

FakeBandStore

package se.juneday.spinnerexample.storage;

import java.util.ArrayList;
import java.util.List;
import se.juneday.spinnerexample.domain.Band;

public class FakeBandStore implements BandStore {

  private List<Band> bands;

  @Override
  public List<Band> bands() {
    if (bands==null) {
      bands = new ArrayList<>();
      bands.add(new Band("Black Flag"));
      bands.add(new Band("Dead Kenedys"));
      bands.add(new Band("Sonic Youth"));
      bands.add(new Band("Minor Threat"));
      bands.add(new Band("Butthole Surfers"));
      bands.add(new Band("Mudhoney"));
    }
    return bands;
  }
}


Links

Spinners (Android Developer site) Spinner (Android API)