Слушатель флажка в ListView с CursorAdapter

У меня проблема очень похожая, чем в этом посте. В каждой строке моего ListView у меня есть флажок со слушателем. Слушатель обновляет строку базы данных.

@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, вызывается прослушиватель, вызывающий новое обновление БД.

Для решения проблемы с прокруткой я хотел использовать adap.changeCursor каждый раз, когда обновляю db, но для второй проблемы это вызывает цикл.

Я также пытаюсь использовать Array, как во втором ответе вышеупомянутого связанного поста, но он использует метод getView od adapter, у меня есть cursorAdapter и я работаю в newView и bindView.

Как я могу решить проблему?

редактировать: решение auselen работает, но оно создает и уничтожает много слушателей, есть ли другое, более эффективное решение?

2 ответа

Решение

Чтобы не вызывать обратные вызовы на слушателе, вы должны отменить регистрацию существующего cb.setOnCheckedChangeListener(null) затем установить cb.setChecked(c.getBoolean(c.getColumnIndex("state"))) затем cb.setOnCheckedChangeListener() снова.

Однако вы должны подумать о лучшем способе использования этого OnCheckedChangeListener, так как вы бы в конечном итоге создали слушателей больше, чем нужно.

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;
        }   
Другие вопросы по тегам