我有自定义arrayadapter用于显示listview的项目。我在item_list.xml文件中有两个textview和一个复选框。我想从listview中删除已检查的项目。但问题是当检查多个项目然后没有从位置正确删除。以下是我的源代码。
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;
}
}
答案 0 :(得分:3)
按位置删除不是一个好的解决方法。 您应该尝试通过对象删除。
以下是示例代码
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;
}
}
修改强>
如果您在删除时获得outofbound exeption,则可以尝试使用此循环
for (String item : ids) {
items.remove(item);
}
答案 1 :(得分:1)
我认为依赖于删除基于索引的项目可能有点复杂,相反,您最好依赖于删除项目本身。我对你的班级进行了一些修改。不确定它是否符合您的要求。
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;
}
}
希望它有所帮助。