Spinnerで選択したアイテムのコードを取得 - 作戦2 本格的にArrayAdapterを拡張 -
作戦1だとtoString()を適切に使えないので作戦2を立案(笑)
かっこよく変換ルールを指定できるようにしちゃいました。
Collections.sort()のComparator見たいなイメージ。
というわけで変換用のinterface
こいつはオブジェクトを受け取って、表示用のテキストを返却するメソッドを定義するよ。
/** * Spinnerに表示するテキストのConvertを行います。 */ public interface Converter<T> { /** * Spinnerに表示したいテキストを返却するように実装してください。 */ public String toDisplayString(T t); }
次にAdapter。
public class KeyValueArrayAdapter<T> extends ArrayAdapter<T> { /** Spinnerに登録したオブジェクトの表示を変換するConverter */ private Converter<T> converter; /** * ArrayAdapter(Context, int)にConverterを追加したコンストラクタ。 * * 必要であれば他のコンストラクタも追加してください。 */ public KeyValueArrayAdapter(Context context, int textViewResourceId, Converter<T> converter) { super(context, textViewResourceId); this.converter = converter; } /** * getViewのOverride。 * 通常の方法ではObjectのtoStringしたものがTextViewに格納されているが、 * その結果を横取りして設定しなおしている。 */ @Override public View getView(int position, View convertView, ViewGroup parent) { Log.d("KeyValueArrayAdapter", "getView start"); TextView view = (TextView) super.getView(position, convertView, parent); view.setText(converter.toDisplayString(getItem(position))); return view; } /** * こちらはSpinnerをクリックしたときに表示されるダイアログみたいなやつ用。 * こっちも上書きしてやらないと、toString()の結果が表示されちゃうよ。 */ @Override public View getDropDownView(int position, View convertView, ViewGroup parent) { TextView view = (TextView) super.getDropDownView(position, convertView, parent); view.setText(converter.toDisplayString(getItem(position))); return view; } }
はまったのがgetDropDownView()も拡張しないといけないってこと。
最初これがわからなくて、Spinnerをタップしたときに表示されるダイアログに表示されるテキストがおかしかった。
最後にActivity
public class SamplePairSpinnerActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Spinner spinner = (Spinner) findViewById(R.id.spinner); KeyValueArrayAdapter<MyObject> adapter = new KeyValueArrayAdapter<MyObject> (this , android.R.layout.simple_spinner_item , new Converter<MyObject>(){ @Override public String toDisplayString(MyObject t) { Log.d("TAG", "convert to" + t.value); return t.value; } }); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); adapter.add(new MyObject("red", "赤")); adapter.add(new MyObject("blue", "青")); adapter.add(new MyObject("green", "緑")); spinner.setAdapter(adapter); } public void handle(View view) { Spinner spinner = (Spinner) findViewById(R.id.spinner); MyObject obj = (MyObject) spinner.getSelectedItem(); Log.d("TAG", "key[" + obj.key + "] value [" + obj.value + "]"); Log.d("TAG", obj.toString()); } }
変わったのはActivityの実装クラスと、コンストラクタに渡すパラメタにConverterが追加されたことくらいかな。
おまけでMyObject
toString()をログ出力なんかに使いやすいようにすることができた。
class MyObject { public String key; public String value; public MyObject(String key, String value) { this.key = key; this.value = value; } @Override public String toString() { return "key[" + key + "] value [" + value + "]"; } }
この方法だとDBから取得したオブジェクトをそのままSpinnerに突っ込めるからとっても便利だよね。