Flutter中SQLite已删除笔记重启后复现问题求助
问题根源与修复方案
核心问题
- 删除数据库记录时用错标识:你在
deleteSelectedNotes里用列表索引i作为数据库的id参数,但数据库的id是自增主键,和列表索引完全无关,导致实际没删除对应的数据,重启后从数据库读取自然又会显示。 - 列表元素删除逻辑有漏洞:正向循环删除列表元素时,删除一个元素后后续元素索引会前移,导致循环跳过部分选中元素,界面上可能没完全移除已删除笔记。
修复步骤
1. 新增存储数据库id的列表
在_MyWidgetState类中添加列表,保存每条笔记在数据库中的真实id:
var noteIds = []; // 存储数据库中的笔记id
2. 修改笔记获取逻辑,保存数据库id
更新_retrieveNotes方法,获取笔记时同时保存数据库id,并正确初始化选中状态列表:
Future<void> _retrieveNotes() async { var tempNoteTitleWait = []; var tempNoteContentWait = []; var tempNoteIdsWait = []; // 临时存储id final database = await DatabaseProvider.database; // 假设selectNotesDB是查询所有Notes的方法,需确保返回id字段 final List<Map<String, dynamic>> result = await selectNotesDB(database); for (final row in result) { tempNoteTitleWait.add(row['title']); tempNoteContentWait.add(row['subtitle']); tempNoteIdsWait.add(row['id']); // 保存数据库id } setState(() { noteTitle = List<String>.from(tempNoteTitleWait); noteContent = List<String>.from(tempNoteContentWait); noteIds = List<int>.from(tempNoteIdsWait); // 更新到状态 originalNoteTitle = List<String>.from(tempNoteTitleWait); originalNoteContent = List<String>.from(tempNoteContentWait); // 重新初始化选中状态和颜色列表 isSelected = List<bool>.filled(noteTitle.length, false, growable: true); tileColor = List<Color>.filled(noteTitle.length, Colors.white, growable: true); }); }
3. 修复删除逻辑
修改deleteSelectedNotes方法,用数据库真实id删除记录,通过倒序删除避免索引混乱:
Future<void> deleteSelectedNotes() async { final database = await DatabaseProvider.database; // 先收集要删除的id和对应的列表索引 List<int> targetIds = []; List<int> targetIndices = []; for (int i = 0; i < noteTitle.length; i++) { if (isSelected[i]) { targetIds.add(noteIds[i]); targetIndices.add(i); } } // 删除数据库中的记录 for (int id in targetIds) { await database.delete( 'Notes', where: 'id = ?', whereArgs: [id], // 使用数据库真实id删除 ); } // 倒序删除列表元素,防止索引偏移 setState(() { targetIndices.sort((a, b) => b.compareTo(a)); for (int index in targetIndices) { noteTitle.removeAt(index); noteContent.removeAt(index); noteIds.removeAt(index); originalNoteTitle.removeAt(index); originalNoteContent.removeAt(index); isSelected.removeAt(index); tileColor.removeAt(index); } appBarActionsEnabled = false; // 可选:退出多选模式 }); }
额外注意
确保selectNotesDB方法返回结果包含id字段,如果是自定义方法,需保证查询所有字段:
Future<List<Map<String, dynamic>>> selectNotesDB(Database db) async { return db.query('Notes'); // 默认查询所有字段 }
内容的提问来源于stack exchange,提问作者qamyk
相关产品推荐
相关产品推荐

