I have a custom CursorAdapter that populates a ListView of Tasks from my database. Each ListView item has a checkbox and a button in it. When pressing the checkbox, the database gets updated to set the task as completed. The problem is that when exiting the ListActivity and returning to the Task list, nothing is updated and the checkboxes don't retain their state.
I have included my CursorAdapter which is where the problem is I think. Is it something to do with the recycling of views maybe? Any help would be much appreciated.
public class ScheduleListAdapter extends CursorAdapter implements
OnClickListener, OnCheckedChangeListener
{
private final static String TAG = "FS: ScheduleList";
private LayoutInflater inflater = null;
private ListView listView = null;
private DataManager db = null;
private ContentValues values = null;
private boolean isCompleted = false;
public ScheduleListAdapter(Context context, Cursor c, ListView listView, DataManager db)
{
super(context, c);
this.listView = listView;
this.db = db;
// Cache the inflater, avoids asking for a new one each time
inflater = LayoutInflater.from(context);
}
/** Determines which button is clicked **/
@Override
public void onClick(View v)
{
final int position = listView.getPositionForView(v);
if (position != ListView.INVALID_POSITION)
{
Logger.e(TAG, "Button clicked at position: " + position);
}
}
/** Determines which star is checked **/
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
final int newValue;
final int position = listView.getPositionForView(buttonView);
if (position != ListView.INVALID_POSITION)
{
buttonView.setChecked(isChecked);
if (isChecked)
{
newValue = 1;
}
else
{
newValue = 0;
}
values = new ContentValues();
values.put(ScheduleTable.KEY_COMPLETED, newValue);
db.update(ScheduleTable.TABLE_NAME, values, position);
// refresh(db.rawQueryGetAll(ScheduleTable.TABLE_NAME));
}
}
/** Makes a new view to hold the data pointed to by cursor. **/
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent)
{
// Create and inflate the listView item view here
View view = inflater.inflate(R.layout.schedule_list_item, parent, false);
ViewHolder holder = new ViewHolder();
holder.cbxCheck = (CheckBox) view.findViewById(R.id.cbx_completed);
holder.txvText1 = (TextView) view.findViewById(R.id.txv_taskListTitle);
holder.txvText2 = (TextView) view.findViewById(R.id.txv_taskListSubTitle1);
holder.txvText3 = (TextView) view.findViewById(R.id.txv_taskListSubTitle2);
holder.btnButton = (Button) view.findViewById(R.id.btn_Edit);
holder.btnButton.setOnClickListener(this);
holder.cbxCheck.setOnCheckedChangeListener(this);
view.setTag(holder);
return view;
}
/** Bind an existing view to the data pointed to by cursor **/
@Override
public void bindView(View view, Context context, Cursor cursor)
{
// Populate list from the cursor here
ViewHolder holder = (ViewHolder) view.getTag();
// Bind the data efficiently with the holder
holder.txvText1.setText(cursor.getString(cursor.getColumnIndex(ScheduleTable.KEY_TITLE)));
holder.txvText2.setText(cursor.getString(cursor.getColumnIndex(ScheduleTable.KEY_DESC)));
holder.txvText3.setText(cursor.getString(cursor.getColumnIndex(ScheduleTable.KEY_DATE)));
isCompleted = Utils.intToBool(cursor.getInt(cursor.getColumnIndex(ScheduleTable.KEY_COMPLETED)));
holder.cbxCheck.setOnCheckedChangeListener(null);
holder.cbxCheck.setChecked(isCompleted);
holder.cbxCheck.setOnCheckedChangeListener(this);
Logger.e(TAG, cursor.getString(cursor.getColumnIndex(ScheduleTable.KEY_TITLE)) + " at position is completed: " + isCompleted);
}
/** Updates the listView when data changes **/
public void refresh(Cursor newCursor)
{
changeCursor(newCursor);
notifyDataSetChanged();
}
private static class ViewHolder
{
TextView txvText1;
TextView txvText2;
TextView txvText3;
CheckBox cbxCheck;
Button btnButton;
}
}