【问题标题】:Remove checkbox selected multiple items from listview android using custom arrayadapter使用自定义arrayadapter从listview android中删除复选框选择的多个项目
【发布时间】: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;
        }
}

【问题讨论】:

    标签: android checkbox android-listview android-arrayadapter


    【解决方案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 你能发布你最新的代码吗,因为有了上面的代码,我可以毫无问题地删除最后一个项目。
    猜你喜欢
    • 2015-06-26
    • 2021-06-17
    • 1970-01-01
    • 2010-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多