Furudateのブログ

プログラミングやネットワーク系の知識・技術がメインのブログ。技術メモ帳的な感じになるかと。岩手から発信していきます。

【Android】リストビューにチェックマークを追加し、条件を満たしたときにチェックを入れる

こんばんは。

Androidのリストビューのrowのレイアウトに、CheckedTextViewを使うとリストビューにチェックマークを入れることができます。
ただ、普通にしているとタッチしたときにチェックがされちゃいます。
設定変更などの時はそれで良いのかもしれませんが、今回は一工夫加えて、タッチしたときはチェックマークの変更をせず、ある条件を満たした時のみチェックを入れられるようにしたいと思います。
このチェックは、タッチで外すことは出来ないようにします。

以下ソースコードです。

ListViewとrowのレイアウト

main_list.xmlにリストビューを定義します。これは普通にやります。

<ListView
     android:id="@+id/TestList"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_alignParentLeft="true"
     android:layout_alignParentTop="true" >
</ListView>

row_checked.xmlに各行のレイアウトを定義します。
これはCheckedTextViewを使います。なお、このレイアウトファイルはデフォルトで用意されているsimple_list_item_multiple_choiceをオーバーライドしたものです。

<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:layout_width="fill_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:gravity="center_vertical"
    android:checkMark="?android:attr/textCheckMark"
    android:paddingLeft="6dip"
    android:paddingRight="6dip"
    android:textColor="@color/white"
/>

リストビューの作成と、チェックマークの操作

ListView lv = (ListView)findViewById(R.id.TestList);
		
String[] value = new String[10];
for (int i = 0; i < rootData.size(); i++){ // データの数だけ実行
	value[i] = "問題" + (i + 1);
}

ArrayAdapter<String> adapter = (new ArrayAdapter<String>(this, R.layout.row_checked, value){});

lv.setAdapter(adapter);
lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

// flagが立っているものは、チェックマークを入れる
for (Integer i = 0; i < 10; i++){
	Integer answer_flag = flag[i];
	if (answer_flag != -1){
		lv.setItemChecked(i, true);
	}
}


/**
 * リストの項目をクリックしたときの処理
 * @params position タッチした場所(一番上は0)
 */
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position, long id){
		// タッチでチェックさせないようにする。フラグがあるものは、何もしない
		ListView listView = (ListView)parent;
		Integer answer_flag = flag[position];

		if (answer_flag == -1){ // フラグがない
			listView.setItemChecked(position, false);
		}else{ // フラグがある
			listView.setItemChecked(position, true);
		}
	}
});

ポイントは以下のとおりです。

  • まずリストを作成します。ここはいつもどおりやります。
  • adapterの行のレイアウトファイルに先ほど作成したrow_checkedを指定します。
  • リストビューにsetChoiceModeを指定します。これでチェックを入れることができるようになりました。ちなみに、CHOICE_MODE_SINGLEにすると、ラジオボタンになります。
  • setItemChecked(position, ture) で、フラグがあるもののみにチェックを入れるようにしています。
  • ListViewの各行をタッチしたときに、setItemCheckedをfalseにすることでタッチしてもチェックを入れないようにしています。

以上です。
どの項目が条件を満たしているかを示したい時などに使えると思います。


なお、どの項目がチェックされているかを判断するには、以下のようにします。

// 選択アイテムを取得
SparseBooleanArray checked = lv.getCheckedItemPositions();

for (int i=0; i<checked.size(); i++) {
    if (checked.valueAt(i)) {
        // true の場合、選択されているアイテム
    }
}

getCheckedItemPositionsで、ListViewのチェックマークが入ったものを取得しています。
しかし、これは過去一度でもチェックマークが入ったものを取得しているので、現在チェックマークが入っていないものも取得してしまいます。
そこで、valueAt()を使うことで現在チェックが入っているものを取得するようにしています。


今回のエントリーは以上です。
それでは。