ListViewを複数選択と単選択で切り替える方法

通常は単選択(Single)モードで、ユーザのメニュー選択により複数選択(Multiple)モードに切り替わるようなListViewを作成する。

まず使えそうだったのが、
API LEVEL 11から追加されたListView.CHOICE_MODE_MULTIPLE_MODALでsetChoiceModeを使って設定する。

listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);

参照URLはココ。
http://techbooster.org/android/ui/3503/

しかし、setMultiChoiceModeListener()を使って専用のリスナをセットしなければならない等、ちょっと面倒。私のやりたいことは2つ目のItemを選択したら、その2つのItemのデータを取り出して、次の画面に遷移できればいいので、そこまで本格的なことはやらないし、API LEVEL7との互換性も保ちたいしということで、普通にAPI LEVEL1から存在するListView.CHOICE_MODE_MULTIPLEを使うことにした。

まずListViewのChoiceModeをCHOICE_MODE_MULTIPLEにする。

listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

次に、これまではListViewのItemにはTextViewを使用していたが、CheckedTextViewに変更することにした。
しかし、これではいつもチェックボックス付きのListViewになってしまうので、チェックボックスを表示・非表示できるようにする。
私のアプリでは、ListAdapterをカスタマイズして使用しているので、overrideしているgetView()を以下のようにする。

class ListAdapterImpl extends BaseAdapter implements ListAdapter {
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		if(convertView == null) {
			convertView = getLayoutInflater().inflate(R.layout.rowdata, parent, false);
		}
		TextView tv = (TextView)convertView.findViewById(R.id.TextView);
		tv.setText(mData.getList().get(position)[0]);

		if(mIsMultiple){
			int[] attrs = { android.R.attr.listChoiceIndicatorMultiple };
			TypedArray ta = convertView.getContext().getTheme().obtainStyledAttributes(attrs);
			Drawable indicator = ta.getDrawable(0);
			((CheckedTextView)tv).setCheckMarkDrawable(indicator);
			ta.recycle();
		} else {
			((CheckedTextView)tv).setCheckMarkDrawable(null);
		}
		return tv;
	}
}

rowdata.xmlはこんな感じ。


あとは、mIsMultipleをT/F切り替えればいいわけだが、getView()を任意で呼び出すのに以下のメソッドを使用したが、ダメだった。

adapter.notifyDataSetChanged();

こいつはDataSetを再設定してはくれるが、表示は変えてくれないらしい。
ちなみにBaseAdapterには

adapter.notifyDataSetInvalidated();

というのもあるが、notifyDataSetChanged()との違いがよくわからない。

結局、表示をし直すために、以下のようにした。

ListView.setAdapter(new ListAdapterImpl())

Adapterを作りなおして、setAdapterをし直す。
他にも手段はあるのかもしれないが、とりあえずこれでOK。

あとはListView.onItemClick()でもsingle用の処理とmultiple用の処理を書分ければ完了!

多分今回は複数選択といっても2個という制限付きだったからこれが楽だったけど、本当に0〜nという条件だったら素直にCHOICE_MODE_MULTIPLE_MODALを使うのが楽そう。


参照URL
http://d.hatena.ne.jp/satosystems/20120315/1331818858
http://techbooster.org/android/application/6550/
http://techbooster.org/android/ui/3503/
http://techbooster.org/android/ui/13946/