Home > Android > [Android] グルーピング機能付きSpinner

[Android] グルーピング機能付きSpinner

Spinnerのドロップダウン時、アイテムをカテゴリ毎にグルーピング表示することでユーザー・エクスペリエンスを向上させることができるケースがあります。
(例:都道府県選択で地方毎にグルーピングする等)

今回はグルーピング機能をもったSpinnerの作り方について書いていきたいと思います。
 

  1. アイテムデータクラス作成
  2. カスタムSpinnerAdapterクラス作成
  3. グループ項目を選択できないようにする
  4. 使い方

 

アイテムデータクラス作成

まず、スピナーのアイテムデータクラスを用意します。

/**
 * グループスピナアイテムクラス
 */
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
Facebook にシェア
[`google_buzz` not found]
[`yahoo` not found]
[`livedoor` not found]
[`friendfeed` not found]
[`tweetmeme` not found]
[`grow` not found]

Comments:0

Comment Form
Remember personal info

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 ミライニトドケ

Home > Android > [Android] グルーピング機能付きSpinner

Search
Feeds
Meta
人気の記事

Return to page top