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

Android ListView自定义适配器删除数据库项后如何自动刷新

问题根因

你现在遇到的列表不刷新、ImageView点击无响应的问题核心是3个:

  • ImageView作为列表项内的可点击子控件,会默认消费点击事件,所以你写在ListView.onItemClickListener里的逻辑根本不会在点击ImageView时触发
  • 你在适配器里给ImageView写的点击逻辑,仅执行了数据库删除操作,没有更新适配器持有的数据源,也没有触发列表刷新通知,所以数据库数据变了界面不会同步
  • 现有代码存在两个功能性bug:一是deleteOne方法错误使用rawQuery执行DELETE语句,实际上不会生效删除操作;二是读取数据库数据时没有给DataModel设置主键ID,按title删除会出现重名误删问题,且适配器里new新的DataModel会丢失ID标识。
修复步骤

1. 修复数据库操作类的逻辑bug

首先修改DataBaseHelper,修正删除逻辑,查询数据时把主键ID赋值给数据模型,避免误删:

// 修正getAllAsList方法,读取ID并赋值给模型
public ArrayList<DataModel> getAllAsList() {
    ArrayList<DataModel> returnList = new ArrayList<>();
    String queryString = "SELECT * FROM " + TODO_TABLE;
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.rawQuery(queryString, null);

    if(cursor.moveToFirst()) {
        do {
            // 读取主键ID
            int todoId = cursor.getInt(0);
            String todoTitle = cursor.getString(1);
            DataModel newTodo = new DataModel(todoTitle);
            newTodo.setId(todoId);
            returnList.add(newTodo);
        } while(cursor.moveToNext());
    }

    cursor.close();
    db.close();
    return returnList;
}

// 修正deleteOne方法,用ID做唯一条件执行删除
public boolean deleteOne(DataModel dModel) {
    SQLiteDatabase db = this.getWritableDatabase();
    // 用SQLite自带delete方法,参数化查询避免SQL注入,按主键删除不会误删
    int affectedRows = db.delete(TODO_TABLE, COLUMN_ID + " = ?", new String[]{String.valueOf(dModel.getId())});
    db.close();
    return affectedRows > 0;
}

额外修复:你原来的空输入判断正则少了转义符,"s*"要改成"\\s*"才能正确匹配空字符串。

2. 修改适配器逻辑,删除后触发列表刷新

修改DataAdapter,复用列表项布局优化性能,删除数据库条目后同步更新数据源、通知列表刷新,不要在getView里重复创建丢失ID的DataModel实例:

publicpublic class DataAdapter extends ArrayAdapter<DataModel> {
    private Context mContext;
    private int mResource;
    private ArrayList<DataModel> mList;
    private DataBaseHelper mDbHelper;

    public DataAdapter(Context context, int resource, ArrayList<DataModel> list, DataBaseHelper dbHelper) {
        super(context, resource, list);
        mContext = context;
        mResource = resource;
        mList = list;
        mDbHelper = dbHelper;
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        // 复用convertView,避免每次滑动都inflate布局造成卡顿
        if (convertView == null) {
            LayoutInflater inflater = LayoutInflater.from(mContext);
            convertView = inflater.inflate(mResource, parent, false);
        }

        // 直接获取当前位置的真实数据,不要new新对象丢失ID
        DataModel currentItem = getItem(position);
        TextView tvTitle = convertView.findViewById(R.id.task);
        ImageView delView = convertView.findViewById(R.id.delView);

        tvTitle.setText(currentItem.getTitle());

        delView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 第一步:删除数据库对应条目
                mDbHelper.deleteOne(currentItem);
                // 第二步:移除适配器数据源里的对应条目
                mList.remove(position);
                // 第三步:通知适配器数据变更,ListView自动刷新
                notifyDataSetChanged();
            }
        });
        return convertView;
    }
}

3. 优化MainActivity逻辑,避免重复创建适配器

不需要每次增删数据都重新new一个适配器,初始化一次即可,增删后直接刷新数据:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    dbHelper = new DataBaseHelper(MainActivity.this);
    assignVariables();
    registerClick();
    // 只初始化一次适配器
    todoAdapter = new DataAdapter(MainActivity.this, R.layout.list_item, dbHelper.getAllAsList(), dbHelper);
    lv.setAdapter(todoAdapter);
}

// 替换原来的showAllToDos为刷新方法
public void refreshTodoList() {
    todoAdapter.clear();
    todoAdapter.addAll(dbHelper.getAllAsList());
    todoAdapter.notifyDataSetChanged();
}

添加待办的逻辑里,数据库插入完成后直接调用refreshTodoList()即可,原来写的lv.setOnItemClickListener如果没有点击整个列表项的其他需求可以直接删除,删除逻辑已经在ImageView的点击监听里处理完成。


内容的提问来源于stack exchange,提问作者Nicole

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 18:36:24