android - 使用自定义数组适配器从 android ListView 中删除选中的多个项目的复选框

标签 android checkbox android-listview android-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;
        }
}

最佳答案

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

这是示例代码

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

关于android - 使用自定义数组适配器从 android ListView 中删除选中的多个项目的复选框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29741602/

相关文章:

android - 陷入 NullPointerexception

android - Android 中的清晰 View

java - fragment 中的画廊

java - 翻译动画无法与 OnClickListener 一起使用

javascript - 仅在选中复选框时显示列表

php - wp_list_categories 的自定义函数将术语列为复选框

javascript - 检查条件后使用 jQuery 取消选中框

java - Android Studio上的错误(方法未从其父类(super class)重写方法)

android - 使用 SimpleAdapter 过滤 listView 数据

java - 安卓 : want to access to a textview in a viewholder in my mainactivity