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

RecyclerView列表项撤销恢复后重启APP消失问题(Kotlin)

问题分析与修复方案

滑动删除RecyclerView列表项后,点击Snackbar的“Undo”按钮可恢复该项,但关闭并重启APP后,刚恢复的项会消失,核心问题出在数据库恢复逻辑和操作方式上,以下是具体分析和修复步骤:

问题根源

  1. 数据库插入操作错误:undoDeleteTask方法使用readableDatabase执行插入,而插入需要写入权限,应该用writableDatabase;同时insert方法的参数使用错误,第二个参数nullColumnHack并非用来指定ID,直接传null和无效值导致数据未正确插入。
  2. 数据恢复不完整:仅传入ID无法恢复任务的完整数据,必须将任务的所有字段信息插入回数据库。
  3. 逻辑时序隐患:滑动删除时先更新数据库位置,此时被删项仍在数据库中,直到Snackbar消失才删除,易导致数据状态不一致。

修复方案

1. 修正undoDeleteTask方法

改为传入完整的Task对象,用可写数据库插入完整的任务数据:

fun undoDeleteTask(task: Task) {
    val db = mHelper.writableDatabase
    val values = ContentValues().apply {
        put(TaskContract.TaskEntry.COLUMN_ID, task.ID)
        put(TaskContract.TaskEntry.COLUMN_TITLE, task.title) // 替换为你的实际字段
        put(TaskContract.TaskEntry.COLUMN_CONTENT, task.content)
        // 添加任务的其他必要字段
    }
    db.insert(TaskContract.TaskEntry.TABLE, null, values)
    db.close()
}

2. 调整Snackbar的Undo回调逻辑

点击Undo时传入完整的被删任务对象,确保恢复完整数据:

.setAction("Undo"){
    undoDeleteTask(removedItem)
    list.add(position, removedItem)
    notifyItemInserted(position)
    updateNotesPositionInDb()
}

3. 优化删除确认逻辑

仅当用户未点击Undo(Snackbar超时或手动关闭)时,才执行数据库删除操作,避免数据状态混乱:

override fun onViewSwiped(position: Int) {
    val removedItem = list.removeAt(position)
    notifyItemRemoved(position)

    val snackBar = Snackbar
        .make((context as Activity).findViewById(R.id.mainLayout), "Task deleted", Snackbar.LENGTH_LONG)
        .setAction("Undo"){
            list.add(position, removedItem)
            notifyItemInserted(position)
            undoDeleteTask(removedItem)
            updateNotesPositionInDb()
        }
        .addCallback(object : BaseTransientBottomBar.BaseCallback<Snackbar>() {
            override fun onDismissed(transientBottomBar: Snackbar?, event: Int) {
                // 排除点击Undo导致的消失事件
                if (event != BaseTransientBottomBar.BaseCallback.DISMISS_EVENT_ACTION) {
                    deleteTask(removedItem.ID)
                    updateNotesPositionInDb()
                }
            }
        })
    snackBar.show()
}

4. 确认deleteTask方法正确性

确保删除操作是基于ID精准删除数据库中的对应任务:

fun deleteTask(id: String) {
    val db = mHelper.writableDatabase
    db.delete(TaskContract.TaskEntry.TABLE, "${TaskContract.TaskEntry.COLUMN_ID} = ?", arrayOf(id))
    db.close()
}

效果说明

修复后,点击Undo按钮会将完整的任务数据写入数据库,重启APP时读取数据库就能正确加载恢复的任务,同时逻辑时序的优化也避免了数据不一致的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 10:50:24