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

如何通过RecyclerView长按位置获取SQLite列值实现删除对应表条目

问题原因
  • 你在MainActivity中全局声明的Stock stock实例,是在onCreate里通过无参构造方法new Stock()创建的空对象,它的id默认值为0,你的SQLite表中不存在id为0的条目,调用db.getStockItem(stock.getID())实际就是查询id=0的条目,返回的Cursor是空集,你未对空Cursor做判断就直接调用cursor.getString(0),直接触发索引越界崩溃。
  • 另外你删除完条目后没有刷新RecyclerView,就算删除成功界面也不会同步更新。
  • DBHandler中的getStockItem方法缺少Cursor有效性判断,只要查询不到结果就会崩溃。
修复步骤

1. 修改MainActivity代码

首先把商品列表改成全局成员,修改长按回调逻辑:

public class MainActivity extends AppCompatActivity implements StockViewInterface {

    private DBHandler db;
    private ArrayList<Stock> allStock; // 把列表改成全局成员
    private StockAdapter stockAdapter; // 适配器也存为全局方便刷新

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        RecyclerView stockView = findViewById(R.id.rvStock);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        stockView.setLayoutManager(linearLayoutManager);
        stockView.setHasFixedSize(true);
        db = new DBHandler(this);
        allStock = db.getAllStock(); // 赋值给全局列表

        if (allStock.size() > 0) {
            stockView.setVisibility(View.VISIBLE);
            stockAdapter = new StockAdapter(this, allStock, this);
            stockView.setAdapter(stockAdapter);
        }
        else {
            stockView.setVisibility(View.GONE);
            Toast.makeText(this, "No Items!", Toast.LENGTH_LONG).show();
        }
    }

    @Override
    public void onLongItemClick(int position) {
        Toast.makeText(this, "long pressed", Toast.LENGTH_SHORT).show();
        // 从全局列表中取出长按位置对应的Stock对象,拿到正确id
        Stock targetStock = allStock.get(position);
        db.deleteStockItem(targetStock);
        // 从列表中移除该条目并刷新适配器
        allStock.remove(position);
        stockAdapter.notifyItemRemoved(position);
        // 列表空了就显示提示
        if (allStock.size() == 0) {
            findViewById(R.id.rvStock).setVisibility(View.GONE);
            Toast.makeText(this, "No Items!", Toast.LENGTH_LONG).show();
        }
    }
}

2. 修复DBHandler的getStockItem方法,增加空判断

避免后续查询不到条目时崩溃:

// Get a single stock item
Stock getStockItem(int id) {
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.query(TABLE_STOCK, new String[] { KEY_ID, KEY_ITEM, KEY_CONDITION, KEY_QUANTITY, KEY_LOCATION, KEY_CATEGORY}, KEY_ID + "=?",
            new String[] {String.valueOf(id)}, null, null, null, null);
    Stock stock = null;
    // 增加Cursor有效性判断
    if (cursor != null && cursor.moveToFirst()) {
        stock = new Stock(Integer.parseInt(cursor.getString(0)), cursor.getString(1), cursor.getString(2), cursor.getInt(3),
                cursor.getString(4), cursor.getString(5));
        cursor.close(); // 用完关闭Cursor避免内存泄漏
    }
    return stock;
}

3. 删掉StockAdapter中的无效代码

你在StockAdapter构造方法中mainActivity = new MainActivity()是错误的写法,不能直接new Activity实例,会导致内存泄漏,直接删除这行即可:

StockAdapter(Context context, ArrayList<Stock> listStock, StockViewInterface stockViewInterface) {
    this.context = context;
    this.listStock = listStock;
    this.mArrayList = listStock;
    this.stockViewInterface = stockViewInterface;
    db = new DBHandler(context);
    // 删掉 mainActivity = new MainActivity(); 这行
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 05:15:03