Spinner の setAdapter で、BaseAdapter を指定する

Android Spinner を使い方としてよく紹介されているのは、ArrayAdapter<String> を使った例である。
確かにシンプルで理解しやすいサンプルになるのだが、実用ではどうだろうか?

例えば、任意のオブジェクト、以下のような オブジェクトのリストを Spinner で選択する場合、

public class Item {
   public int id;
   public String name;
   public Item(){}
}

ArrayAdapter を使うと、

Spinner spinner = (Item)findViewById(R.id.groupSpinner);
ArrayAdapter<Item> adapter = new ArrayAdapter<Item>(this, android.R.layout.simple_spinner_item);

次に、adapter.add で追加、
Item は、toString() を適切に実装しなければならない。

BaseAdapter を使い、getDropDownView を実装すれば toString() オーバーライドを記述しなくても良い。

toString()の結果が何らかの理由で Spinner での表示ができないものは ArrayAdapter ではつらい。

実用で、以下のように、、

final List<Item> list = new ArrayList<Item>();

リストを作成して、

Spinner spinner = (Spinner)findViewById(R.id.spinner1);
spinner.setAdapter(new BaseAdapter(){
   LayoutInflater infrater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
   @Override
   public View getView(int position,View convertView,ViewGroup parent){
      // Spinner 閉じてる時の View
      View view = convertView==null ? infrater.inflate(android.R.layout.simple_spinner_item,null) : convertView;
      *1.setText(list.get(position).name);
      return view;
   }
   @Override
   public View getDropDownView(int position,View convertView,ViewGroup parent){

      // ドロップダウン中の View
      View view = convertView==null ? infrater.inflate(android.R.layout.simple_spinner_dropdown_item,null) : convertView;
      *2.setText(list.get(position).name);
      return view;
   }
   public long getItemId(int position){
      return position;
   }
   public Object getItem(int position){
      return list.get(position);
   }
   public int getCount(){
      return list.size();
   }
});

--------------
任意のアクションで

int position = spinner.getSelectedItemPosition();

Item item = list.get(position);

で選択した Item を参照する。

*1:TextView)view.findViewById(android.R.id.text1

*2:TextView)view.findViewById(android.R.id.text1