CheckBoxの付きListViewでのチェック行の取得について

8,594 views
Skip to first unread message

TOTO

unread,
Jun 12, 2012, 9:45:56 AM6/12/12
to 日本Androidの会
初めまして,TOTOと申します。
現在題名の通りCheckBoxの付きListViewを作成しているのですが、
onCreateの中で

ListView listview=(ListView) this.findViewById(R.id.list);
Button button=(Button)findViewById(R.id.button1);

このようにListViewを宣言し、レイアウト上のボタンを押すと,ダイアログを表示させpositivibuttonでチェックの入った項目を取っ
てきたいのですが


button.setOnClickListener(new OnClickListener() {
  //イベントの定義

@Override
public void onClick(View view) {
dialog = new
AlertDialog.Builder(ListTestActivity.this); //アラートダイアログ
の生成
dialog.setPositiveButton("テスト", new
DialogInterface.OnClickListener(){ //ポジティブボタンの設定

@Override
public void onClick(DialogInterface dialog, int which)
{ //ポジティブボタンの動作定義

SparseBooleanArray positions =
listview.getCheckedItemPositions(); //チェックの付いた行の配列を生成

}
}
}
});

と、書いたのですが、ListViewの方でチェックをつけてもpositionsには全てfalseが入った要素数12の配列が出来てしまいます。
webでも検索したのですが、このような問題で引っかからず困っています。
何かご存知の方がいらっしゃいましたらご教授の程よろしくお願いいたします。

Naoyuki Miyata

unread,
Jun 12, 2012, 8:56:40 PM6/12/12
to android-g...@googlegroups.com
宮田です。

Adapterの設定はどのように行ってありますか?

下記サイトを参考になると思います。


2012/6/12 TOTO <electr...@gmail.com>

--
このメールは Google グループのグループ「日本Androidの会」の登録者に送られています。
このグループに投稿するには、android-g...@googlegroups.com にメールを送信してください。
このグループから退会するには、android-group-j...@googlegroups.com にメールを送信してください。
詳細については、http://groups.google.com/group/android-group-japan?hl=ja からこのグループにアクセスしてください。


TOTO

unread,
Jun 13, 2012, 12:48:25 AM6/13/12
to 日本Androidの会
ご返答ありがとうございます。
以下がAdapterのソースコードです。
Model_ClassDataというデータクラスのListをListViewに紐付けします。
1行にTextViewが4つ横に並び、更にその横にチェックボックスがあるレイアウトになっています。

紹介していただいたページを参考にして、ArrayAdapterにcheckedTextViewを一つ置き、Stringの配列で試してみたとこ

チェックされた行を正しく取得することに成功しました。
しかし以下のような独自のレイアウトを用意しArrayAdapterを継承したクラスを使用すると、チェック状態を取ってきてくれません。
ということはAdapterを継承したクラスの中でチェックの状態を返却するようなメソッドを用意しなければいけなければいけないのでしょうか?
また先程試した時にArrayAdapterを使用した時には
listview.setChoiceMode(ListView.CHOICE_MODE_SINGLE)のようにListViewのモード選択が
機能しましたが、独自のレイアウトを用意しArrayAdapterを継承したクラスを使用した場合、これが機能せずどのモードを指定しても複数選択が
可能な状態になってしまうことに気づきました。
本題とは逸れてしまうかもしれませんが、この辺も関係あるのでしょうか。もしお分かりでしたらご教授の程よろしくお願いいたします。

import java.util.List;

import android.content.Context;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.TextView;
/**
* レイアウトに合わせて独自に拡張したArrayAdapterのアダプタサブクラス
* ListViewとModel_ClassDataのメンバを紐付けする。
*/
public class CustomAdapter extends ArrayAdapter<Model_ClassData> {

private LayoutInflater inflater; //レイアウト拡張のためインフレータの宣言
private ViewHolder holder; //データバインドクラスの宣言
private Model_ClassData classdata; //押された行のデータ
private CheckBox checkbox;

//コンストラクタ
public CustomAdapter(Context context, List<Model_ClassData> objects)
{
super(context, 0, objects);
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE); //インフレータをサービスから
呼び出す
}

/**
* ListViewにデータが表示される際に呼び出されるメソッド
* @param convertView position番目のListのViewの情報(LinearLayout)
* @param position Listの番号
* @param parent Listを束ねるwigdet?(ListView)
*/
@Override
public View getView( int position, View convertView, ViewGroup
parent) {
if (convertView == null) { // 行に表示させるデータが用意されていなければ
lesson_list_row.xmlファイルを呼び出す。
convertView = inflater.inflate(R.layout.lesson_list_row, null); //リス
トに表示させる行のレイアウトファイルをinflateする
holder = new ViewHolder(); // 一時的にデータを保持するクラスをインスタンス化
holder.settTimeTable ((TextView)
convertView.findViewById(R.id.textview1));

holder.settTheme((TextView)convertView.findViewById(R.id.textview2));
holder.settDemandCost((TextView)
convertView.findViewById(R.id.textview3));

holder.settPoint((TextView)convertView.findViewById(R.id.textview4));

holder.settBox((CheckBox)convertView.findViewById(R.id.ordercheckbox)); //
lesson_list_rowのCheckBoxをholderに参照させる。
convertView.setTag(holder); //setTagで現在の行のholderをタグに格納し、行の再表示時に使用できる
ようにする。
}else{ // 行に表示させるデータが用意されている場合
holder=(ViewHolder)convertView.getTag(); //再表示するholderのデータをsettagでセッ
トしたtagから読み込む。
}

classdata = (Model_ClassData)getItem(position); //Listの該当する行のオブジェクトを取
得する
holder.gettTimeTable().setText(classdata.getTimeTable());
holder.gettTheme().setText(classdata.getTheme());
holder.gettDemandCost().setText(classdata.getLessonDemandCost() +
"円");
holder.gettPoint().setText(classdata.getPointPer()+"%");
holder.gettBox().setTag(classdata); //チェックボックスに該当する行のデータをタグで持たせる。
holder.gettBox().setOnClickListener(new View.OnClickListener() { //チェ
ックボタン押下時のイベント設定
@Override
public void onClick(View v) { //チェックボタン押下時のイベント定義
checkbox = (CheckBox)v; //現在操作しているチェックボタンの参照を取得
Model_ClassData
tempClassData=(Model_ClassData)checkbox.getTag(); //チェックした行のデータを参照させる
tempClassData.setChecked(checkbox.isChecked()); //チェックボックスの状態をデータの
boolean変数にセットする。
} //チェックされていればtrue,チェックされていなければfalse
});
holder.gettBox().setChecked(classdata.isChecked()); //データクラスのboolean変
数に従ってチェックボックスの状態を変化させる。trueならチェック、falseならチェックしない。




return convertView; //リストビューの一行分のレイアウトViewを返す。
}



}

Daisuke Adachi

unread,
Jun 13, 2012, 8:58:29 AM6/13/12
to android-g...@googlegroups.com

安達と申します。 

以下が参考になるでしょう。
- Custom ListView with ability to check items

Androidアプリ開発入門リンク集: 

TOTO

unread,
Jun 13, 2012, 10:35:27 AM6/13/12
to 日本Androidの会
足立様ありがとうございます。教えていただいたサイトを参考にしたところ、getViewの中で呼び出すViewをCheckableインターフェース
を用いたViewを用意すれば
リスト押下時にチェックボックスにチェックが入り、setChoiceModeも機能するようになりました。ありがとうございました。

参考になればと思い、以下に作成したサンプルコードを貼っておきます。

package com.ListTest;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;


public class ListTestActivity extends Activity {
private static final String[] GENRES = new String[] { "Action",
"Adventure", "Animation", "Children", "Comedy", "Documentary",
"Drama", "Foreign", "History", "Independent", "Romance", "Sci-Fi",
"Television", "Thriller" };

private ListView listview;
private Button button;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
listview = (ListView) findViewById(R.id.list);
button = (Button) findViewById(R.id.button1);

CAdapter adapter=new CAdapter(this,GENRES);

listview.setAdapter(adapter);
listview.setItemsCanFocus(false);
listview.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listview.setOnItemClickListener(new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
SparseBooleanArray checked = listview.getCheckedItemPositions();
for (int i = 0; i < checked.size(); i++) {
if (checked.valueAt(i) == true) {
Log.i(getClass().getSimpleName(),
"" + GENRES[checked.keyAt(i)] + "");
}
}
}
});
button.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
ArrayList<String> tempArray=new ArrayList<String>();
SparseBooleanArray checked = listview.getCheckedItemPositions();
for (int i = 0; i < checked.size(); i++) {
if (checked.valueAt(i) == true) {
tempArray.add(GENRES[checked.keyAt(i)]);
}
}
for(String s:tempArray){
Toast.makeText(getApplicationContext(), s, 0).show();
}
}
});
}

class ViewHolder {
TextView textview;
CheckBox checkbox;
}

class CAdapter extends ArrayAdapter<String> {
private ViewHolder holder;

public CAdapter(Context context, String[] objects) {
super(context, 0, objects);
}

@Override
public View getView(int position, View convertView, ViewGroup
parent) {
if (convertView == null) {
convertView = new cCheckBox(getContext());
holder = new ViewHolder();
holder.textview = (TextView)
convertView.findViewById(R.id.textView1);
holder.checkbox = (CheckBox)
convertView.findViewById(R.id.checkBox1);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.textview.setText(getItem(position).toString());
ListView listview = (ListView) parent;
holder.checkbox.setChecked(listview.isItemChecked(position));
return convertView;
}
}
}


package com.ListTest;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.CheckBox;
import android.widget.Checkable;
import android.widget.CheckedTextView;
import android.widget.LinearLayout;
import android.widget.ListView;

public class cCheckBox extends LinearLayout implements Checkable {
private CheckBox checkbox;

public cCheckBox(Context context) {
super(context);

View
view=((LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.row,
this,false);
checkbox=(CheckBox)view.findViewById(R.id.checkBox1);
addView(view);
}


@Override
public void setChecked(boolean checked) {
checkbox.setChecked(checked);

}

@Override
public boolean isChecked() {
return checkbox.isChecked();
}

@Override
public void toggle() {
setChecked(!isChecked());

}

}
Reply all
Reply to author
Forward
0 new messages