【问题标题】:ListView item not getting removed in BaseExpandableListAdapterListView 项目未在 BaseExpandableListAdapter 中删除
【发布时间】:2017-11-09 15:52:01
【问题描述】:

我有一个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();
                }
            }
        }
    }

适配器类

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

我的适配器类正在扩展 BaseExpandableListAdapter

【问题讨论】:

  • 发布完整代码
  • @Pavneet_Singh 已编辑。
  • 删除项目后,您只需清除适配器并将列表重新设置为适配器即可。
  • 尝试将hasStableIds 更改为false
  • @Pavneet_Singh 像魅力一样工作

标签: java android listview expandablelistview


【解决方案1】:

首先:您需要更改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 将被提升为 long 但不会自动允许 inverse(导致数据丢失)

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

解决方案:使用int 或在使用remove as 时将转换应用于int

 laptops.remove((int)position);

【讨论】:

  • 谢谢你的回答先生!
  • @JohnJoe 因为编译器发现有一个可用的remove 方法版本可以接受一个对象,因此它会变得聪明并将long 转换为Long,但不幸的是我们不想要它(不想通过匹配对象删除项目,但我们想按位置删除项目),我很高兴我能提供帮助
【解决方案2】:

在我将long 更改为int 并将hasStableIds 设置为false 后,它就像魅力一样。

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

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

【讨论】:

  • 要了解这种行为,您可以在下面查看我的答案,尽管这是由于AutoBoxing
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-03
  • 2016-06-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-22
  • 2016-11-27
相关资源
最近更新 更多