如何通过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
相关产品推荐
相关产品推荐

