如何从 android 列表视图中删除多个选定项目并将其从适配器中删除?

How to delete multiple selected item from android listview and remove it from the adapter as well?

所以,我有一个列表视图和一个将数据填充到列表视图中的适配器。

列表项中的每一行都有一个复选框。片段中有一个按钮,允许使用其 ID 从数据库中删除选中的项目。

但是,我希望发生这种情况:

  1. 用户checks/unchecks他想删除的项目。
  2. 然后他单击片段上的删除多个项目按钮。
  3. 项目已从数据库中删除。
  4. 项目不再显示在列表视图中。即它们被删除了。

我已经完成了上述所有 3 个步骤。但我正在为最后一个而苦苦挣扎。单击图像按钮时,我可以从列表视图中删除单个项目,但问题出在多个项目上。

适配器代码:


public class ReqFoodAdapter extends BaseAdapter implements CompoundButton.OnCheckedChangeListener {
    private Activity activity;
    private ArrayList<HashMap<String, String>> data;
// the arraylist that holds the data of the checked items
    private ArrayList<String> checkedList = new ArrayList<String>();
    private static LayoutInflater inflater=null;
    Bitmap image,receivedBitmap;



    public ReqFoodAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
        activity = a;
        data=d;
        inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// initializing each item in the arraylist
        for(int i = 0; i < data.size(); i++ ){
            checkedList.add(i,"0");
        }
    }
//method to return the arraylist to the fragment
    public ArrayList<String> getCheckedList(){
        return checkedList;
    }

    @Override
    public int getCount() {
        return data.size();
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        View vi = convertView;

        if(convertView == null)
            vi = inflater.inflate(R.layout.list_row_req_food, null);
        TextView fid = vi.findViewById(R.id.lv_req_id);
        TextView name = vi.findViewById(R.id.item_name);
        TextView qty = vi.findViewById(R.id.item_req_qty);
        TextView ngoAdd = vi.findViewById(R.id.ngo_address);
        TextView resName = vi.findViewById(R.id.ngoName);
        ImageView type = vi.findViewById(R.id.type);
        ImageView thumb_image = vi.findViewById(R.id.ngo_image);
        ImageView btn_req_confirm = vi.findViewById(R.id.btn_req_confirm);
//checkbox in each row
        CheckBox checkBox = vi.findViewById(R.id.chkThisRequest);
        checkBox.setOnCheckedChangeListener(this);
        HashMap<String, String> food = new HashMap<String, String>();

        food = data.get(position);
        checkBox.setTag(position + "," + food.get(FoodRequests.KEY_ID));
        fid.setText(food.get(FoodRequests.KEY_ID));
        name.setText(food.get(FoodRequests.KEY_NAME));
        qty.setText(food.get(FoodRequests.KEY_REQ_QTY) + " kg");
        ngoAdd.setText(food.get(FoodRequests.KEY_NGO_ADD));

        resName.setText(food.get(FoodRequests.KEY_NGO_NAME));
        if(food.get(FoodRequests.KEY_TYPE).equals("Veg"))
            type.setImageResource(R.drawable.veg);
        else if(food.get(FoodRequests.KEY_TYPE).equals("Non-Veg"))
            type.setImageResource(R.drawable.non_veg);


        btn_req_confirm.setTag(position + "," + food.get(FoodRequests.KEY_ID));
        btn_req_confirm.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {


                String arrayTag[] = ((String) view.getTag()).split(",");
                String key = arrayTag[1];
                //Update the database using key here
                int pos = Integer.parseInt(arrayTag[0]);
                data.remove(pos);
                ReqFoodAdapter.this.notifyDataSetChanged();


            }
        });
        return vi;
    }




    // onchecked change of the checkbox, change the checkedList value to the id
    @Override
    public void onCheckedChanged(CompoundButton compoundButton, boolean b) {

        String arrayTag[] = ((String) compoundButton.getTag()).split(",");
        String key = arrayTag[1];
        int pos = Integer.parseInt(arrayTag[0]);
        if(b) {
            checkedList.set(pos, key);

        }else{
            checkedList.set(pos,"0");

        }
    }
    // method to remove item
    public void removeItem(int index){
        data.remove(ReqFoodAdapter.this.getItem(index));
    }

    public void updateListView(){
        notifyDataSetChanged();
    }
}

* 片段代码*:



public class FoodRequests extends Fragment {

    public FoodRequests() {
    }



    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        rootview = inflater.inflate(R.layout.fragment_food_requests, container, false);

        lvReqFood = rootview.findViewById(R.id.list_req_food);
        arrListReqFood = new ArrayList<HashMap<String, String>>();
        new LoadReqFood().execute();
        btnConfirmAll = rootview.findViewById(R.id.btnConfirmAll);
        // button confirm multiple reuqests
        btnConfirMultiple = rootview.findViewById(R.id.btnConfirmMultiple);

        return rootview;
    }

    private class LoadReqFood extends AsyncTask<String, String, String >{
        ProgressDialog loadingRequests;



        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            loadingRequests.dismiss();
            adapter = new ReqFoodAdapter(getActivity(), arrListReqFood);
            lvReqFood.setAdapter(adapter);
            btnConfirMultiple.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                   // get the checked list
                    ArrayList<String> checkedList = adapter.getCheckedList();
                    try {
                        for (int i = 0; i < checkedList.size(); i++){
                                temp.put(String.valueOf(i + 1), checkedList.get(i));
                        }

                    joAllRequests.put("requests",temp.toString());
                    }catch (JSONException j){
                        j.printStackTrace();
                    }
                    // update the database using each of the id of the list
                    new UpdateRequest().execute();

                }
            });
        }
    }




    private class UpdateRequest extends AsyncTask<String, String, String>{
        String msg;



        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            Toast.makeText(getContext(), msg, Toast.LENGTH_SHORT).show();
            ArrayList<String> checkedList = adapter.getCheckedList();
            for (int i = 0; i < checkedList.size(); i++){
                if(!checkedList.get(i).equals("0")) {
                    String arrayTag[] = checkedList.get(i).split(",");
                    int pos = Integer.parseInt(arrayTag[0]);
                    adapter.removeItem(pos);
                }
            }
            adapter.updateListView();

        }
    }
}

因此,数据已加载,所选项目已更新,但当我希望从列表视图中删除该项目时,它会引发 ArrayIndexOutOfBound 异常。这是因为,当我从数据中删除一个项目时,它的位置会发生变化,而当我传递另一个项目以给定位置删除时,它会引发错误。

如何处理?

或者有更好的方法来解决我的问题吗?

为了避免位置变化的问题,只需将for循环的方向反转即可,所以代码如下:

    ArrayList<String> checkedList = adapter.getCheckedList();
    for (int i = checkedList.size() - 1; i => 0; i--){
        if(!checkedList.get(i).equals("0")) {
            String arrayTag[] = checkedList.get(i).split(",");
            int pos = Integer.parseInt(arrayTag[0]);
            adapter.removeItem(pos);
        }
    }
    adapter.resetCheckedList();
    adapter.updateListView();

检查列表也需要在删除项目后重置,因此可以像这样更改 adpater 的构造函数:

public ReqFoodAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
    activity = a;
    data=d;
    inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    resetCheckedList();
}

public void resetCheckedList(){
    checkedList.clear();
    // initializing each item in the arraylist
    for(int i = 0; i < data.size(); i++ ){
        checkedList.add(i,"0");
    }
}

希望对您有所帮助!