我创建了一个带复选框的自定义ListView。我想在“删除”菜单选项选项中删除所选项目。 我在CheckBox上处理onCheckedChanged事件。这里我维护一个ArrayList来记下所选元素的位置。现在,当用户选择“删除”菜单项时,我会从ListAdapter的ArrayList中删除选择的项目。
以下是我的代码,
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
names = new ArrayList<String>();
names.add("first");
names.add("second");
names.add("three");
names.add("four");
names.add("five");
names.add("six");
names.add("seven");
names.add("eight");
names.add("nine");
listAdapter = new SelfAdapter(this,names);
this.setListAdapter(listAdapter);
}
@Override
public boolean onOptionsItemSelected(MenuItem menuItem){
int menuId = menuItem.getItemId();
ArrayList<Integer> selectedItems;
switch(menuId){
case R.id.delitem:
Log.d(TAG,"del item selected");
selectedItems = listAdapter.getSelected();
**//pick the selected position items and delete them from the
// listadapter arraylist**
for(Integer element: selectedItems){
Log.d(TAG,"Selected:"+element.toString());
names.remove(element.intValue());
listAdapter.notifyDataSetChanged();
}
}
return true;
}
以下是自定义适配器的代码,
class SelfAdapter extends ArrayAdapter<String>{
ViewHolder holder = new ViewHolder();
private Activity context;
private ArrayList<String> names;
private String TAG = "SelfAdapter";
ArrayList<Integer> checkedPos; **//contains the selected items position**
public SelfAdapter(Context context, ArrayList names) {
super(context,R.layout.checkboxnlist, names);
this.context = (Activity) context;
this.names = names;
checkedPos = new ArrayList<Integer>();
}
@Override
public View getView(int position, View convertView, ViewGroup parent){
final int listPosition = position;
if(convertView == null){
LayoutInflater inflater = context.getLayoutInflater();
convertView = inflater.inflate(R.layout.checkboxnlist,parent,false);
holder.chkBox = (CheckBox)convertView.findViewById(R.id.chkvw);
holder.txtView = (TextView)convertView.findViewById(R.id.txtvw);
convertView.setTag(holder);
}
else{
holder = (ViewHolder) convertView.getTag();
}
holder.txtView.setText(names.get(position));
holder.chkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Log.d(TAG,"listPosition:"+listPosition);
if(isChecked){
checkedPos.add(new Integer(listPosition));
}
else{
checkedPos.remove(listPosition);
}
}
});
return convertView;
}
public ArrayList<Integer> getSelected(){
return checkedPos;
}
static class ViewHolder{
TextView txtView;
CheckBox chkBox;
}
}
现在的问题是,如果选择第1个,第2个项目(例如),那么我会看到错误的项目被删除,并且列表视图在完全错误之后填充。稍后,如果我尝试删除它正在抛出“索引越界异常”的项目。我想在getView方法中代码出错了。
有人可以帮助我找出这里的错误。
由于
答案 0 :(得分:1)
从names
删除元素时,还需要从checkedPos
数组中删除元素。否则,两个数组将具有不同的长度。然后,当您再次尝试时,checkedPos
将超过names
,并最终导致索引超出范围异常。
此外,当您从names
删除时,您无法使用正常的迭代器。如果您应该删除索引1和2处的名称,那么当您删除名称1时,名称2会向上移动到位置1.但您的索引不会相应地更新。最简单的解决方案是向后遍历位置数组,从names
的末尾删除,然后从开头删除。
P.S。将序数(“第一”,“第二”)切换到列表中间的基数(“三”,“四”等)有点奇怪。
答案 1 :(得分:0)
你必须删除 names = new ArrayList&lt; STRING&gt;();
但是你删除了selectedItems;