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

RecyclerView侧滑删除后数据库删除错误问题排查与解决

解决RecyclerView侧滑删除后数据库删错数据的问题

问题根源

你当前代码的错误在于:侧滑后先调用adapter.removeItem(cachedPosition)把元素从列表中移除,此时listArray已经发生了变化。当Snackbar自动消失(用户未点击撤销)时,调用adapter.deleteFromDB(dbManager, cachedPosition),此时listArray[cachedPosition]对应的已经不是你要删除的那个元素了,导致传入数据库的id错误,最终删错数据。

最优方案选择

你的两种思路里,无需先删数据库再删列表,也不需要修改现有数据库删除函数(它本身是正确的,通过id删除是可靠的)。核心要改的是:删除数据库时直接使用缓存的待删除元素的id,而不是依赖列表当前的位置。

具体修改步骤

1. 调整MainActivity中的Snackbar回调逻辑

把删除数据库的操作改成直接用缓存的cachedItem的id,不需要通过Adapter的位置去取:

Snackbar.make(binding.rv, "Deleted", Snackbar.LENGTH_SHORT)
    .setAction("Undo") { }
    .addCallback(object: BaseTransientBottomBar.BaseCallback<Snackbar>() {
        override fun onDismissed(transientBottomBar: Snackbar, event: Int) {
            if (event == DISMISS_EVENT_ACTION) {
                adapter.restoreItem(cachedPosition, cachedItem)
                // 恢复后重新计算总和,保证金额显示正确
                val b = dbManager.total().toBigDecimal().setScale(2, RoundingMode.HALF_UP).toString()
                binding.tvResult.text = "Сумма $b ₾"
            } else {
                // 直接用缓存元素的id删除数据库数据,完全不受列表变化影响
                dbManager.removeItem(cachedItem.id.toString())
            }
        }
    })
    .show()

2. 删除Adapter中多余的deleteFromDB函数

现在直接在MainActivity里调用dbManager.removeItem即可,Adapter里的这个函数可以删掉,避免后续误用:

// 删掉以下无用函数
// fun deleteFromDB (dbManager: DbManager, pos: Int){
//     dbManager.removeItem(listArray[pos].id.toString())
// }

方案优势

  • 保留原有的“先删列表、延迟删数据库”流程,撤销操作只需要恢复列表,无需操作数据库,逻辑更简洁
  • 直接用缓存元素的id删除数据库,完全不受列表位置变化的影响,从根源避免删错数据
  • 现有数据库的removeItem函数无需修改,通过主键id删除是最可靠的数据库操作方式

内容的提问来源于stack exchange,提问作者Антон Кузнецов

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 04:15:41