ListView 项目未在 BaseExpandableListAdapter 中删除

ListView item not getting removed in BaseExpandableListAdapter

我有一个expandablelistView。单击列表时,将显示两个按钮。单击删除按钮时,它假设删除子项和父项。不幸的是,没有删除任何内容。

 ArrayList<ListObj> groupList= new ArrayList<ListObj>();
     listview = (ExpandableListView) findViewById(R.id.exlistView);
     expListAdapter = new ExpandableListAdapter(AddMonthlyExpenses.this,getApplication(), groupList);
     listview.setAdapter(expListAdapter);
     retrieveList(name);

public void retrieveList(String name) {
        groupList.clear();
        database = mdb.getReadableDatabase();
        Cursor cursor = database.rawQuery("SELECT * FROM " + MyDatabaseHelper.TABLE__TASK + " WHERE Name = ? ", new String[]{name}, null);
        if (cursor != null && cursor.getCount() > 0) {
            groupList = new ArrayList<ListObj>();
            while (cursor.moveToNext()) {
                int iD = cursor.getInt(cursor.getColumnIndex("ID"));
                String month = cursor.getString(cursor.getColumnIndex("Month"));
                double budget = cursor.getDouble(cursor.getColumnIndex("Budget"));
                groupList.add(new ListObj(iD,month,budget));
                if (expListAdapter != null) {
                    expListAdapter.add(iD, month, budget,"edit");
                   listview.deferNotifyDataSetChanged();
                }
            }
        }
    }

适配器class

 public class ExpandableListAdapter extends BaseExpandableListAdapter {

    private Context context;
    private ArrayList<ListObj> laptops;
    Activity parentActivity;
    private LayoutInflater mInflater;
    SQLiteDatabase database;
    MyDatabaseHelper mdb;

    public ExpandableListAdapter(Activity parentActivity, Context context, ArrayList<ListObj> laptops) {
        this.parentActivity= parentActivity;
        this.context = context;
        this.laptops = laptops;
        mInflater = LayoutInflater.from(context);
        mdb= new MyDatabaseHelper(context);
    }

    public Object getChild(int groupPosition, int childPosition) {
        ArrayList<ItemDetails> productList =
                laptops.get(groupPosition).getProductList();
        return productList.get(childPosition);
    }


    public void add(int id, String month, double budget) {
        String[] splited = month.split("\s+");
        ListObj obj = new ListObj(id, month, budget);
        obj.setYear(splited[1]);
        obj.setMonth(splited[0]);
        obj.setBudget(budget);
        obj.setID(id);
//        mySection.put(obj);
        laptops.add(obj);
        this.notifyDataSetChanged();

        ArrayList<ItemDetails> productList = obj.getProductList();

        ItemDetails detailInfo = new ItemDetails();
        productList.add(detailInfo);
        obj.setProductList(productList);
    }

    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    public int getCount() {
        return laptops.size();
    }

    public void removeItem(long position) {
        laptops.remove(position);
        notifyDataSetChanged();
    }


    public ListObj getItem(int position) {
        return laptops.get(position);
    }

    public View getChildView(final int groupPosition, final int childPosition,
                             boolean isLastChild, View convertView, ViewGroup parent) {
        if (convertView == null) {
            LayoutInflater infalInflater = (LayoutInflater)
                    context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.child_item, null);
        }

        Button editButton = (Button)convertView.findViewById(R.id.editButton);
        Button deleteButton = (Button)convertView.findViewById(R.id.deleteButton);

        deleteButton.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {
                AlertDialog.Builder builder = new AlertDialog.Builder(parentActivity);
                builder.setMessage("Do you want to remove?");
                builder.setCancelable(false);
                builder.setPositiveButton("Yes",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
//                                Toast.makeText(context,"button clicked  "+ groupPosition,Toast.LENGTH_LONG).show();
                                ListObj headerInfo = laptops.get(groupPosition);
                                deleteData(headerInfo.getID());
                                removeItem(groupPosition);
                                Toast.makeText(context,"list deleted",Toast.LENGTH_LONG).show();
                                notifyDataSetChanged();
                            }
                        });
                builder.setNegativeButton("No",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                dialog.cancel();
                            }
                        });
                AlertDialog alertDialog = builder.create();
                alertDialog.show();
            }
        });


        return convertView;
    }

    public void deleteData(long id)
    {
        database = mdb.getWritableDatabase();
        database.delete(MyDatabaseHelper.TABLE_EXPENSES, MyDatabaseHelper.ID2 + "=?", new String[]{id + ""});
    }

    public int getChildrenCount(int groupPosition) {
        ArrayList<ItemDetails>itemDetails=laptops.get(groupPosition).getProductList();
        return itemDetails.size();
    }

    public Object getGroup(int groupPosition) {
        return laptops.get(groupPosition);
    }

    public int getGroupCount() {
        return this.laptops.size();
    }

    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    public View getGroupView(int groupPosition, boolean isExpanded,
                             View convertView, ViewGroup parent) {
        convertView = mInflater.inflate(R.layout.expenses_adapter, null);
        TextView month = (TextView) convertView.findViewById(R.id.textMonth);
        TextView budget = (TextView) convertView.findViewById(R.id.textAmount);
        TextView year = (TextView) convertView.findViewById(R.id.textYear);
        month.setText(laptops.get(groupPosition).getMonth());
        budget.setText(laptops.get(groupPosition).getBudget()+"");
        year.setText(laptops.get(groupPosition).getYear());
        return convertView;
    }


    public boolean hasStableIds() {
        return true;
    }

    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }
}

我的适配器 class 正在扩展 BaseExpandableListAdapter

在我将 long 更改为 int 并将 hasStableIds 设置为 false 后,效果很好。

public void removeItem(int position) {
        laptops.remove(position);
        notifyDataSetChanged();
    }

我传递了错误的数据类型。但奇怪的是,我没有收到任何错误。

首先:您需要更改 hasStableIds,因为对列表的删除和添加操作会更改列表的索引,所以 true 意味着,可扩展列表视图可以重用对应 ID 的视图,并且它可以导致不必要地重用脏(删除)视图的问题

public boolean hasStableIds() {
    return false;
}

其次:正如您提到的,您需要使用 int 而不是 long 因为这样做

 laptops.remove(position);

long 位置将 AutoBoxed 变为 Long 因此它将调用 remove 的覆盖版本 ObjectArrayList#remove(Object) 结果为

 laptops.remove(LongObject); 

所以它会尝试从 ArrayList 中搜索并删除一个 Long 对象(其值是位​​置),尽管列表中没有 Long 对象。

为什么选择拳击?

按照

的规则

Widening Primitive Conversion

int will be promoted to long but inverse is not automatically allowed (result in lost of data)

所以 long 将是 boxedLong 以调用更具体的删除方法 ArrayList#remove(Object)

解决方案:使用 int 或在使用 remove 作为

时将转换应用于 int
 laptops.remove((int)position);