2

この投稿と非常によく似た問題があります。ListView のすべての行に、リスナー付きのチェックボックスがあります。Listener 更新データベース行。

@Override
public void bindView(View v, Context context, Cursor c) {
    TextView tvA = (TextView) v.findViewById(R.id.adi_tv_activity);
    CheckBox cb = (CheckBox) v.findViewById(R.id.adi_cbox);
    tvA.setText(c.getString(c.getColumnIndex("name")));
    final long id = c.getLong(c.getColumnIndex("_id"));
    final Context ctx = context;
    cb.setOnCheckedChangeListener(new OnCheckedChangeListener(){
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            ObjDBF dbf = new ObjDBF(ctx); //Object thet update db
            if(isChecked) {
                dbf.tbActivitiesUpdateState(id, true);  
            } else {   
                dbf.tbActivitiesUpdateState(id, false);     
            }
        }               
    });
    if (c.getBoolean(c.getColumnIndex("state"))) {
        cb.setChecked(true);
    } else {
        cb.setChecked(false);
    }
}

2つの問題があります。

  1. スクロールの問題。リストの移動 画面から消える行のチェックボックスの状態が失われました。
  2. setChecked を使用するたびに、リスナーが呼び出され、新しいデータベースが更新されます。

スクロールの問題を解決するために、dbを更新するたびにadapter.changeCursorを使用したかったのですが、2番目の問題ではループが発生します。

上記のリンクされた投稿の2番目の回答のように配列を使用しようとしますが、getView odアダプターメソッドを使用します。cursorAdapterがあり、newViewとbindViewで動作します

どうすれば問題を解決できますか?

編集: auselen ソリューションは機能しますが、多くのリスナーを作成および破棄します。他のより効率的なソリューションはありますか?

4

2 に答える 2

3

リスナーでコールバックがトリガーされないようにするには、既存のコールバックを登録解除してから再度cb.setOnCheckedChangeListener(null)設定する必要があります。cb.setChecked(c.getBoolean(c.getColumnIndex("state")))cb.setOnCheckedChangeListener()

OnCheckedChangeListenerただし、必要以上にリスナーを作成することになるため、それを使用するより良い方法を考える必要があります。

于 2012-11-26T14:56:45.037 に答える
0
private SparseBooleanArray bolarray;
public class ViewHolder{
        CheckBox checked_displayName;
        int contact_id;
        String displayName;
        boolean isChecked=false;
    }

public void bindView(View v, Context context, Cursor cursor) 
{

ViewHolder viewHolder=new ViewHolder();

viewHolder.checked_displayName=(CheckBox) 
v.findViewById(R.id.checked_displayName);

viewHolder.displayName=cursor.getString(cursor.getColumnIndex(PROJECTION[0]));

viewHolder.checked_displayName.setText(viewHolder.displayName);

viewHolder.checked_displayName.setTag(viewHolder);

if(!bolarray.get(viewHolder.contact_id)){
            bolarray.put(viewHolder.contact_id, false);
            viewHolder.checked_displayName.setChecked(false);
            viewHolder.isChecked=false;
        }else{

            bolarray.put(viewHolder.contact_id, true);
            viewHolder.checked_displayName.setChecked(true);
            viewHolder.isChecked=true;
        }   
于 2013-12-13T08:03:19.860 に答える