使用自定义数组适配器从列表视图 android 中删除选中的多个项目的复选框

Remove checkbox selected multiple items from listview android using custom 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;
        }
}

按位置删除不是一个好的解决方法。 您应该尝试通过对象移除。

这是示例代码

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);
     }

我认为依赖于根据索引删除项目可能有点复杂,相反,您最好依靠删除项目本身。我对你的 class 做了一些修改。不知道能不能满足你的要求。

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;
 }
}

希望对您有所帮助。