我的适配器没有正确更新我的列表视图选项
My adapter not update correctly my listview option
我有下一个问题。当我从我的适配器中的 ListView 中删除一个项目时,CheckBox 的状态从列表中的项目更改,为什么?还有,如何解决这个问题?
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();
}
如果我删除 项目 4
项目 5 的复选框恰好被删除 项目 4
选中
编辑 1:添加了 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;
}
编辑 2:添加了 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();
}
只是猜测,但我认为您需要在 getView 方法中更新复选框的状态。从数据集中删除对象时,需要确保在 getView 方法中更新了 isChecked。现在,当您从 dataSet 中删除一个数据并更新列表项时,CheckBox 的状态不会改变。
你的代码中有这样的东西吗?:
@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());
// ...
}
因为我发现您没有在 CheckBox 的点击侦听器中更新数据集。
所以你也需要在其中添加这个,或者像这样:
case R.id.list_checkbox:
CheckBox checkBox = v.findViewById(R.id.list_checkbox);
dataRowModel.isChecked(checkBox.isChecked());
// ... rest of the code
编辑:
问题是您仅在 View (convertView) 为 null 时才更新 CheckBox!您需要将该代码从 if (convertView == null) 移开,因为它仅在创建视图时被调用,并且当您调用 notifyDataSetChanged 时,不会再次创建视图并且未到达您的 if 块。
补充一下@vilpe89 的回答,问题不是你没有在 getView()
中调用 setChecked()
,而是你在错误的地方调用它:
viewHolder.checkbox.setChecked(dataRowModel.isChecked());
仅当 convertView == null
时才调用此行,但更新列表时 convertView
不会为空。因此,要解决您的问题,您需要将该行移动到 if else
语句之后,如下所示:
viewHolder.checkbox.setOnClickListener(this);
viewHolder.checkbox.setChecked(dataRowModel.isChecked());
viewHolder.checkbox.setTag(position);
我有下一个问题。当我从我的适配器中的 ListView 中删除一个项目时,CheckBox 的状态从列表中的项目更改,为什么?还有,如何解决这个问题?
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();
}
如果我删除 项目 4
项目 5 的复选框恰好被删除 项目 4
选中编辑 1:添加了 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;
}
编辑 2:添加了 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();
}
只是猜测,但我认为您需要在 getView 方法中更新复选框的状态。从数据集中删除对象时,需要确保在 getView 方法中更新了 isChecked。现在,当您从 dataSet 中删除一个数据并更新列表项时,CheckBox 的状态不会改变。
你的代码中有这样的东西吗?:
@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());
// ...
}
因为我发现您没有在 CheckBox 的点击侦听器中更新数据集。
所以你也需要在其中添加这个,或者像这样:
case R.id.list_checkbox:
CheckBox checkBox = v.findViewById(R.id.list_checkbox);
dataRowModel.isChecked(checkBox.isChecked());
// ... rest of the code
编辑:
问题是您仅在 View (convertView) 为 null 时才更新 CheckBox!您需要将该代码从 if (convertView == null) 移开,因为它仅在创建视图时被调用,并且当您调用 notifyDataSetChanged 时,不会再次创建视图并且未到达您的 if 块。
补充一下@vilpe89 的回答,问题不是你没有在 getView()
中调用 setChecked()
,而是你在错误的地方调用它:
viewHolder.checkbox.setChecked(dataRowModel.isChecked());
仅当 convertView == null
时才调用此行,但更新列表时 convertView
不会为空。因此,要解决您的问题,您需要将该行移动到 if else
语句之后,如下所示:
viewHolder.checkbox.setOnClickListener(this);
viewHolder.checkbox.setChecked(dataRowModel.isChecked());
viewHolder.checkbox.setTag(position);