You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android开发:SwipeMenuListView删除Item异常问题求助

解决SwipeMenuListView删除Item后界面不更新及索引越界问题

问题描述

您好,我遇到了一个无法解决的问题,恳请您的帮助。我尝试删除SwipeMenuListView中的Item,但未能成功,相关代码如下:

list= (SwipeMenuListView) findViewById(R.id.listView1);
groups = new UserData(getApplication()).getUserGroups();
if (groups == null) groups = new ArrayList<String>();
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, groups.toArray(new String[0]));
list.setAdapter(adapter);

list.setOnMenuItemClickListener(new SwipeMenuListView.OnMenuItemClickListener() {
    @Override
    public boolean onMenuItemClick(int position, SwipeMenu menu, int index) {
        switch (index) {
            case 0:
                try {
                    groups.remove(position);
                    adapter.notifyDataSetChanged();
                    Log.d("TAG","onMenuClickListener"+index+" position is "+ position);
                    break;
                } catch (Exception e) {
                    Log.d("TAG","error " + e);
                }
        }
        // false : close the menu; true : not close the menu
        return false;
    }
});

list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        Intent intent = new Intent(GroupActivity.this, MapsActivity.class);
        intent.putExtra("GRUPID", groups.get(position));
        startActivity(intent);
    }
});

当我尝试删除Item时,该Item并未消失,再次点击删除按钮时出现以下错误:

java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1.

我推测Item实际上已被删除,但仍在界面上显示。再次感谢您的帮助。


问题分析与解决方案

我来帮你拆解下这个问题:你之所以遇到删除后界面不更新、第二次点击还报索引越界的情况,核心原因是你创建ArrayAdapter时用了groups.toArray(new String[0]),这相当于给Adapter传了一个和原始groups集合完全独立的新数组。也就是说,Adapter内部维护的数据源和你后续修改的groups根本不是同一个对象——你删了groups里的元素,但Adapter里的数据还是原来的,所以调用notifyDataSetChanged()也没用,界面当然不会更新。等第二次点击时,界面上显示的还是旧的Item位置,但groups已经少了一条,自然就会出现索引越界的错误。

解决起来很简单,只需要改一行代码:把ArrayAdapter的初始化方式改成直接传入原始的groups集合,而不是转成数组:

// 原来的代码
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, groups.toArray(new String[0]));

// 修改后的代码
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, groups);

这样ArrayAdapter就会直接关联groups这个ArrayList,当你调用groups.remove(position)后,再调用adapter.notifyDataSetChanged(),Adapter就能立刻感知到数据变化,界面也会同步更新,索引越界的问题也会随之消失。

另外给你个小优化建议:如果你的列表项比较多,删除Item时可以用adapter.notifyItemRemoved(position)替代notifyDataSetChanged(),前者只会刷新被删除位置及之后的Item,效率更高;当然如果你的列表比较简单,用notifyDataSetChanged()也完全没问题。


内容的提问来源于stack exchange,提问作者Oğuzhan ÖZCAN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:18:16