使用自定义arrayadapter从listview android中删除复选框选择的多个项目
Posted
技术标签:
【中文标题】使用自定义arrayadapter从listview android中删除复选框选择的多个项目【英文标题】:Remove checkbox selected multiple items from listview android using custom arrayadapter 【发布时间】:2015-06-26 19:22:58 【问题描述】:我有自定义 arrayadapter 用于显示列表视图的项目。我在 item_list.xml 文件中有两个文本视图和一个复选框。我想从列表视图中删除选中的项目。但问题是当检查多个项目然后没有从位置正确删除。下面是我的源代码。
public class MainActivity extends Activity
ListView listView;
Button btnDelete;
ArrayList<String> items = new ArrayList<String>();
ArrayList<String> ids = new ArrayList<String>();
CustomAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView1);
btnDelete = (Button) findViewById(R.id.btnDelete);
for (int i = 0; i < 20; i++)
items.add("Chk " + i);
adapter = new CustomAdapter(MainActivity.this, R.layout.custome_list,
items);
listView.setAdapter(adapter);
btnDelete.setOnClickListener(new OnClickListener()
@Override
public void onClick(View v)
if (ids.size() > 0)
for (int i = 0; i < ids.size(); i++)
items.remove(ids.get(i));
// items.remove(items.get(adapter.getItemViewType(ids.get(i))));
// items.remove(adapter.getItemViewType(ids.get(i)));
adapter.notifyDataSetChanged();
);
public class CustomAdapter extends ArrayAdapter<String>
List<String> items;
int resource;
public CustomAdapter(Context context, int resource, List<String> items)
super(context, resource, items);
this.items = items;
this.resource = resource;
@Override
public View getView(final int position, View convertView, ViewGroup parent)
final int pos = position;
ViewHolder holder = null;
if (convertView == null)
holder = new ViewHolder();
LayoutInflater inflater = getLayoutInflater();
convertView = inflater.inflate(resource, null);
holder.chk = (CheckBox) convertView.findViewById(R.id.chk);
holder.txt = (TextView) convertView.findViewById(R.id.txt);
convertView.setTag(holder);
else
holder = (ViewHolder) convertView.getTag();
holder.txt.setText(items.get(position));
// you have to reload the check states
holder.chk.setOnCheckedChangeListener(null);
holder.chk.setChecked(ids.contains(items.get(position)));
holder.chk
.setOnCheckedChangeListener(new OnCheckedChangeListener()
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked)
if (isChecked)
ids.add(items.get(position));
System.out.println("IDS A: " + ids.toString());
else
if (ids.contains(items.get(position)))
//int i = ids.indexOf(position);
ids.remove(items.get(position));
System.out.println("IDS R: "
+ ids.toString());
);
return convertView;
public class ViewHolder
CheckBox chk;
TextView txt;
【问题讨论】:
【参考方案1】:按位置删除不是一个好的解决方法。 您应该尝试按对象删除。
这是示例代码
public class MainActivity extends Activity
ListView listView;
Button btnDelete;
ArrayList<String> items = new ArrayList<String>();
ArrayList<String> ids = new ArrayList<String>();
CustomAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView1);
btnDelete = (Button) findViewById(R.id.btnDelete);
for (int i = 0; i < 20; i++)
items.add("Chk " + i);
adapter = new CustomAdapter(MainActivity.this, R.layout.custome_list,
items);
listView.setAdapter(adapter);
btnDelete.setOnClickListener(new OnClickListener()
@Override
public void onClick(View v)
if (ids.size() > 0)
for (int i = 0; i < ids.size(); i++)
items.remove(ids.get(i));
// items.remove(items.get(adapter.getItemViewType(ids.get(i))));
// items.remove(adapter.getItemViewType(ids.get(i)));
adapter.notifyDataSetChanged();
);
public class CustomAdapter extends ArrayAdapter<String>
List<String> items;
int resource;
public CustomAdapter(Context context, int resource, List<String> items)
super(context, resource, items);
this.items = items;
this.resource = resource;
@Override
public View getView(final int position, View convertView, ViewGroup parent)
final int pos = position;
ViewHolder holder = null;
if (convertView == null)
holder = new ViewHolder();
LayoutInflater inflater = getLayoutInflater();
convertView = inflater.inflate(resource, null);
holder.chk = (CheckBox) convertView.findViewById(R.id.chk);
holder.txt = (TextView) convertView.findViewById(R.id.txt);
convertView.setTag(holder);
else
holder = (ViewHolder) convertView.getTag();
holder.txt.setText(items.get(position));
// you have to reload the check states
holder.chk.setOnCheckedChangeListener(null);
holder.chk.setChecked(ids.contains(position));
holder.chk
.setOnCheckedChangeListener(new OnCheckedChangeListener()
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked)
if (isChecked)
ids.add(items.get(position));
System.out.println("IDS A: " + ids.toString());
else
if (ids.contains(items.get(position)))
//int i = ids.indexOf(position);
ids.remove(items.get(position));
System.out.println("IDS R: "
+ ids.toString());
);
return convertView;
public class ViewHolder
CheckBox chk;
TextView txt;
编辑
如果您在删除时遇到出站异常,您可以尝试改用此循环
for (String item : ids)
items.remove(item);
【讨论】:
我有新问题,当我向下滚动列表视图时,选中的项目复选框值未选中。它的原因是什么? @jack 在上面的答案中,您应该替换这行代码 - holder.chk.setChecked(ids.contains(position));使用以下行 -holder.chk.setChecked(ids.contains(items.get(position))); 当删除最后的记录,如 Chk 15 到 Chk 20 然后 arrayindexoutofbound 生成【参考方案2】:我认为依赖于基于索引删除项目可能有点复杂,相反,最好依赖于删除项目本身。我对你的课做了一些修改。不确定它是否符合您的要求。
public class MainActivity extends Activity
ListView listView;
Button btnDelete;
ArrayList<String> items = new ArrayList<String>();
ArrayList<String> selectedItems = new ArrayList<String>();
CustomAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView1);
btnDelete = (Button) findViewById(R.id.btnDelete);
for (int i = 0; i < 20; i++)
items.add("Chk " + i);
adapter = new CustomAdapter(MainActivity.this, R.layout.custome_list, items);
listView.setAdapter(adapter);
btnDelete.setOnClickListener(new OnClickListener()
@Override
public void onClick(View v)
if (selectedItems.size() > 0)
for (int i = 0; i < selectedItems.size(); i++)
boolean isremoved = items.remove(selectedItems.get(i));
// items.remove(items.get(adapter.getItemViewType(ids.get(i))));
// items.remove(adapter.getItemViewType(ids.get(i)));
System.out.println();
//selectedItems.clear();
((CustomAdapter) listView.getAdapter()).notifyDataSetChanged();
);
public class CustomAdapter extends ArrayAdapter<String>
List<String> items;
int resource;
public CustomAdapter(Context context, int resource, List<String> items)
super(context, resource, items);
this.items = items;
this.resource = resource;
@Override
public View getView(final int position, View convertView, ViewGroup parent)
final int pos = position;
ViewHolder holder = null;
if (convertView == null)
holder = new ViewHolder();
LayoutInflater inflater = getLayoutInflater();
convertView = inflater.inflate(resource, null);
holder.chk = (CheckBox) convertView.findViewById(R.id.checkBox1);
holder.txt = (TextView) convertView.findViewById(R.id.textView1);
convertView.setTag(holder);
else
holder = (ViewHolder) convertView.getTag();
holder.txt.setText(items.get(position));
// you have to reload the check states
holder.chk.setOnCheckedChangeListener(null);
holder.chk.setChecked(selectedItems.contains(items.get(position)));
holder.chk.setOnCheckedChangeListener(new OnCheckedChangeListener()
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
if (isChecked)
selectedItems.add(items.get(position));
System.out.println("IDS A: " + selectedItems.toString());
else
if (selectedItems.contains(items.get(position)))
int i = selectedItems.indexOf(items.get(position));
selectedItems.remove(i);
System.out.println("IDS R: " + selectedItems.toString());
);
return convertView;
public class ViewHolder
CheckBox chk;
TextView txt;
希望对你有帮助。
【讨论】:
我有新问题,当我向下滚动列表视图时,选中的项目复选框值未选中。它的原因是什么? @jack 你试过我发布的代码了吗?我认为即使您向下滚动,此代码也可以工作。 当我从列表视图中删除最后一项时,引发了 arrayindexoutofbound 异常。 @jack 你能发布你最新的代码吗,因为有了上面的代码,我可以毫无问题地删除最后一个项目。 让我们continue this discussion in chat.以上是关于使用自定义arrayadapter从listview android中删除复选框选择的多个项目的主要内容,如果未能解决你的问题,请参考以下文章
Android中Spinner下拉列表(使用ArrayAdapter和自定义Adapter实现)
Android中Spinner下拉列表(使用ArrayAdapter和自定义Adapter实现) .
ListView:setItemChecked 仅适用于标准 ArrayAdapter - 在使用自定义 ArrayAdapter 时不起作用?
Android零基础入门第40节:自定义ArrayAdapter