- 2012-10-28 (日) 19:26
- Android
Spinnerのドロップダウン時、アイテムをカテゴリ毎にグルーピング表示することでユーザー・エクスペリエンスを向上させることができるケースがあります。
(例:都道府県選択で地方毎にグルーピングする等)
今回はグルーピング機能をもったSpinnerの作り方について書いていきたいと思います。
アイテムデータクラス作成
まず、スピナーのアイテムデータクラスを用意します。
/**
* グループスピナアイテムクラス
*/
public class GroupSpinnerItem {
//==== 変数 ====================================================//
private boolean isGroup; // グループフラグ
private String itemName; // アイテム名
//==== メソッド ================================================//
/**
* コンストラクタ
* @param isGroup グループフラグ
* @param itemName アイテム名
*/
public GroupSpinnerItem(boolean isGroup, String itemName) {
this.isGroup = isGroup;
this.itemName = itemName;
}
}
このクラスにはアイテムがグループかどうかを表すフラグ(isGroup)とアイテム名(itemName)をメンバ変数として持たせておきます。
カスタムSpinnerAdapterクラス作成
独自の見た目を実現するため、新たにAdapter派生クラスを用意してやります。
いくつか方法はありますが、今回はBaseAdapterクラスの派生クラスとして実装していきます。
BaseAdapterの派生クラスではgetCount()、 getItem()、getItemId()、getView()という4つのメソッドの実装が必須となっています。
これらのメソッドではそれぞれ適切な情報を返さなければなりません。詳細については次のテーブルを見てください。
| メソッド | 説明 |
|---|---|
| getCount | 表示項目数を返します。特別なことをしない限りはアイテム数をそのまま返せばOKです。 |
| getItem | アイテムを返します。必要なければnull固定でも何でも構いません。 |
| getItemId | アイテムに紐付いた任意のIDを返します。必要なければ0固定でも何でも構いません。 |
| getView | アイテム部に表示するViewを返します。 |
実装が必須なのは上記4つのメソッドだけですが、SpinnerAdapterクラスには getView() に加えてドロップダウン時に使用されるViewを返すための getDropDownView() というメソッドがあります。
このメソッドを実装していないとドロップダウン時の表示が意図したものにならないため、実装漏れがないように注意しましょう!
/**
* グループスピナアダプタクラス
*/
public class GroupSpinnerAdapter extends BaseAdapter {
//==== 変数 ====================================================//
private ArrayList<GroupSpinnerItem> itemList = new ArrayList<GroupSpinnerItem>(); // アイテムリスト
private LayoutInflater inflater; // インフレータ
//==== メソッド ================================================//
/**
* コンストラクタ
*/
public GroupSpinnerAdapter(Context context) {
inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
/**
* アイテムを追加する。
* @param item アイテム
*/
public void addItem(GroupSpinnerItem item) {
itemList.add(item);
}
public int getCount() {
return itemList.size();
}
public Object getItem(int position) {
return itemList.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
return createView(position, convertView, parent, false);
}
@Override
public View getDropDownView(int position, View convertView,
ViewGroup parent) {
return createView(position, convertView, parent, true);
}
/**
* アイテムViewを作成する。
*/
private View createView(int position, View convertView, ViewGroup parent, boolean isDropDown) {
TextView tvName = null;
if(convertView instanceof TextView) {
tvName = (TextView)convertView;
}
if(tvName == null) {
tvName = (TextView)inflater.inflate(android.R.layout.simple_spinner_item, parent, false);
}
GroupSpinnerItem item = itemList.get(position);
if(item.isGroup) {
//-==- グループタイトル -==-//
if(isDropDown) {
tvName.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
tvName.setText(item.itemName);
tvName.setBackgroundColor(Color.BLUE);
}
}
else {
//-==- アイテム項目 -==-//
String text = " " + item.itemName;
tvName.setText(text);
tvName.setBackgroundColor(Color.TRANSPARENT);
}
return tvName;
}
}
アイテムの管理方法もいろいろと考えられますが、ここではArrayListクラスを使っています。
addItem() はアイテム設定のために追加したメソッドです。
createView() ではインフレータを用いてアイテムViewを作成しています。
グループ項目を選択できないようにする
プログラムによってはグループ部分を選択できないようにしたいこともあります。
アイテムの選択可否設定を行う場合は isEnable() をオーバーライドします。
引数で対象アイテム位置が渡されるので対応したアイテムを取得し、グループだった場合はfalseを返して選択無効に、アイテムだった場合はtrueを返して選択可能になるようにします。
public class GroupSpinnerAdapter extends BaseAdapter {
...
@Override
public boolean isEnabled(int position) {
return (itemList.get(position).isGroup == false);
}
}
使い方
ここまでのコードに関しては好きな場所で定義しておけば大丈夫です。
使う側のコードは次のようになります。
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout llRoot = new LinearLayout(this);
llRoot.setOrientation(LinearLayout.VERTICAL);
setContentView(llRoot);
//==== スピナ初期化 ====//
Spinner spnrGroup = new Spinner(this);
GroupSpinnerAdapter adapter = new GroupSpinnerAdapter(this);
adapter.addItem(new GroupSpinnerItem(true, "グループ1"));
adapter.addItem(new GroupSpinnerItem(false, "アイテム1-1"));
adapter.addItem(new GroupSpinnerItem(false, "アイテム1-2"));
adapter.addItem(new GroupSpinnerItem(false, "アイテム1-3"));
adapter.addItem(new GroupSpinnerItem(true, "グループ2"));
adapter.addItem(new GroupSpinnerItem(false, "アイテム2-1"));
adapter.addItem(new GroupSpinnerItem(true, "グループ3"));
adapter.addItem(new GroupSpinnerItem(false, "アイテム3-1"));
adapter.addItem(new GroupSpinnerItem(false, "アイテム3-2"));
spnrGroup.setAdapter(adapter);
//==== スピナ追加 ====//
llRoot.addView(spnrHoge);
}
}
関連サイト
Developers:Spinner
Developers:BaseAdapter
関連があると思われる記事:
- [Android] Spinnerの基本的な使い方
- [Android] メニュー処理
- [Android] マルチスレッド(その1)
- [C#] overrideとnewの違い
- [Android] 画面の向きを取得
- Newer: [C#] サービスのインストールとデバッグ
- Older: [Android] プリファレンスでデータ保存
Comments:0
Trackbacks:0
- Trackback URL for this entry
- http://gacken.com/wp/program/android/1927/trackback/
- Listed below are links to weblogs that reference
- [Android] グルーピング機能付きSpinner from ミライニトドケ
