Reputation: 210
I have the next problem. When I delete an item from my ListView in my adapter the state of the CheckBox change from item in list, Why? and, how can solve this problem?
public class CustomAdapter extends ArrayAdapter<RowModel> implements View.OnClickListener {
private ArrayList<RowModel> DataSet;
Context context;
public CustomAdapter(ArrayList<RowModel> data, Context context) {
super(context, R.layout.list_item_main, data);
this.DataSet = data;
this.context = context;
}
@Override
public void onClick(View v) {
int position = (Integer) v.getTag();
Object object = getItem(position);
RowModel dataRowModel = (RowModel) object;
switch (v.getId()) {
case R.id.list_checkbox:
CheckBox checkBox = v.findViewById(R.id.list_checkbox);
int bool = (checkBox.isChecked()) ? 1 : 0;
new ListFacade(context).UpdateState(dataRowModel.getRowid(), bool);
break;
case R.id.list_delete_button:
new ListFacade(context).DeleteRow(dataRowModel.getRowid());
DataSet.remove(object);
break;
}
notifyDataSetChanged();
updateWidgetToChange();
}
if I delete the item 4
the checkbox of item 5 happens to be selected by the deletion of item 4
EDIT 1: added getView
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
RowModel dataRowModel = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
ViewHolder viewHolder; // view lookup cache stored in tag
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.list_item_main, parent, false);
viewHolder.checkbox = convertView.findViewById(R.id.list_checkbox);
viewHolder.checkbox.setChecked(dataRowModel.isChecked());
viewHolder.title = convertView.findViewById(R.id.list_title);
viewHolder.classes = convertView.findViewById(R.id.list_classes);
viewHolder.rowid = convertView.findViewById(R.id.list_rowid);
viewHolder.delete_button = convertView.findViewById(R.id.list_delete_button);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.rowid.setText(dataRowModel.getStringRowid());
viewHolder.title.setText(dataRowModel.getAction());
viewHolder.classes.setText(dataRowModel.getType());
viewHolder.checkbox.setOnClickListener(this);
viewHolder.checkbox.setTag(position);
viewHolder.delete_button.setOnClickListener(this);
viewHolder.delete_button.setTag(position);
// Return the completed view to render on screen
return convertView;
}
Edit 2: Added ListFacade
public void UpdateState(int rowid, int bool){
SQLiteDatabase conn = new SqliteHandler(context).getWritableDatabase();
String strSQL = "UPDATE TODO_LIST SET CHECKED='"+ bool +"' WHERE ROWID = "+ rowid;
conn.execSQL(strSQL);
conn.close();
}
public void DeleteRow(int rowid){
SQLiteDatabase conn = new SqliteHandler(context).getWritableDatabase();
conn.delete("TODO_LIST", "ROWID=?", new String[]{String.valueOf(rowid)});
conn.close();
}
Upvotes: 1
Views: 37
Reputation: 1539
To add to @vilpe89's answer, the problem isn't that you aren't calling setChecked()
in getView()
, it's that you're calling it in the wrong spot:
viewHolder.checkbox.setChecked(dataRowModel.isChecked());
You call this line only if convertView == null
, except that when you update the list convertView
will not be null. Therefore, to fix your problem, you need to move that line to after the if else
statement, like so:
viewHolder.checkbox.setOnClickListener(this);
viewHolder.checkbox.setChecked(dataRowModel.isChecked());
viewHolder.checkbox.setTag(position);
Upvotes: 0
Reputation: 4702
Just guessing but I think that you need to get the check box's state updated in getView-method. When you remove the object from dataSet, you need to make sure the isChecked is updated in the getView-method. Now when you remove the one data from dataSet and the list items are updated, the CheckBox's state is not changed.
Do you have something like this in your code?:
@Override
public View getView(int position, View convertView, @NonNull ViewGroup parent) {
// Other code...
RowModel model = getItem(position);
CheckBox cb = (CheckBox) convertView.findViewById(R.id.list_checkbox);
cb.setChecked(model.isChecked());
// ...
}
Because I'm seeing that you are not updating the dataset in your CheckBox's click listener.
So you need to add this in there also, or something like this:
case R.id.list_checkbox:
CheckBox checkBox = v.findViewById(R.id.list_checkbox);
dataRowModel.isChecked(checkBox.isChecked());
// ... rest of the code
Edit:
The problem is that you are only updating the CheckBox when the View (convertView) is null! You need to move that code away from the if (convertView == null) because it gets only called when the View is created and when you call notifyDataSetChanged, the Views are not created again and your if-block is not reached.
Upvotes: 3