Checkbox listener in ListView with CursorAdapter
Asked Answered
H

2

2

I have a problem very similar than this post. In every row of my ListView I have a checkbox with a listener. The Listener update databse row.

@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);
    }
}

I have 2 problems.

  1. Scrolling problem. Moving the list I lost the checkbox state for row that disappear from screen.
  2. Any time I use setChecked the listenr is called causing a new db update.

For risolving scrolling problem I wanted to use adapter.changeCursor every time I update db, but for second problem it cause a loop.

I try also to use a use an Array as in the second answer of above linked post, but it use the method getView od adapter, I have a cursorAdapter and do work in newView and bindView

How can I solve the problem?

edit: auselen solution works but it creates and destroys a lot of listeners, there is an other more efficient solution?

Highoctane answered 26/11, 2012 at 14:15 Comment(2)
What happens if you move "if block" before setting CheckedChange listener? to get rid of old listener as well, you may have to do something like setOnCheckedChangeListener(null) -> setChecked -> setOnCheckedChangeListener(new Listener)Nickelic
it works!!! thanks. If you transform the coment in an answer I accept thatHighoctane
N
3

To avoid triggering callbacks on listener, you should unregister existing one by cb.setOnCheckedChangeListener(null) then set cb.setChecked(c.getBoolean(c.getColumnIndex("state"))) then cb.setOnCheckedChangeListener() again.

However you should think of a better way of using that OnCheckedChangeListener, since you would end up creating listeners more than needed.

Nickelic answered 26/11, 2012 at 14:56 Comment(0)
R
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;
        }   
Redbud answered 13/12, 2013 at 8:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.