编辑:看来此错误仅发生在“重新启动”时,而不会发生在热重载时。
我面临的问题是,已从 SQLLite 数据库中删除的注释在重新启动后又回来了。我不确定为什么会发生这种情况,例如,我删除了一个注释,然后重新启动应用程序,相同的注释重新出现在屏幕上。这很奇怪,因为之前我使用相同的代码删除了注释,但它们没有回来并且永远消失了。
你知道为什么会发生这种情况吗?似乎注释在删除后仍保留在数据库中,然后一旦检索到数据库,它们就会返回,但我检查了并且每次都会调用await database.delete()。
import 'package:flutter/material.dart';
import 'package:notepad/screens/Note.dart';
import 'dart:async';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
//Singleton
class DatabaseProvider {
static Database? _database;
static bool _isDatabaseInitialized = false;
static Future<Database> get database async {
if (_isDatabaseInitialized) {
return _database!;
}
_database = await _initDatabase();
_isDatabaseInitialized = true;
return _database!;
}
static Future<Database> _initDatabase() async {
// Set the path to the database. Note: Using the `join` function from the
// `path` package is best practice to ensure the path is correctly
// constructed for each platform.
final path = join(await getDatabasesPath(), 'notes.db');
return await openDatabase(
path,
// When the database is first created, create a table to store notes.
onCreate: (db, version) {
// Run the CREATE TABLE statement on the database.
return db.execute(
'CREATE TABLE Notes(id INTEGER PRIMARY KEY, title TEXT, subtitle TEXT)',
);
},
// Set the version. This executes the onCreate function and provides a
// path to perform database upgrades and downgrades.
version: 1,
);
}
}
class ListOfNotes extends StatefulWidget {
const ListOfNotes({super.key});
@override
State<ListOfNotes> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<ListOfNotes> {
bool _isInitialized = false;
var noteTitle = [];
var noteContent = [];
late var originalNoteTitle = [];
late var originalNoteContent = [];
late var isSelected =
List<bool>.filled(noteTitle.length, false, growable: true);
late var tileColor =
List<Color>.filled(noteTitle.length, Colors.white, growable: true);
var appBarActionsEnabled = false;
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
itemCount: noteTitle.length,
prototypeItem: ListTile(
contentPadding: EdgeInsets.all(10),
title:
Text(noteTitle.firstWhere((element) => true, orElse: () => '')),
subtitle: Text(
noteContent.firstWhere((element) => true, orElse: () => '')),
),
itemBuilder: (context, index) {
return ListTile(
title: Text(noteTitle[index]),
subtitle: Text(noteContent[index]),
onLongPress: () {
toggleSelection(index);
toggleActions();
},
onTap: () {
_editNote(context, index);
},
selected: isSelected[index],
tileColor: tileColor[index],
enabled: true);
}),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () {
_navigateAndDisplaySelection(context);
},
),
);
}
Future<void> deleteSelectedNotes() async {
final database = await DatabaseProvider.database;
// Remove the Note from the database.
for (int i = 0; i < noteTitle.length; i++) {
if (isSelected[i] == true) {
await database.delete(
'Notes',
// Use a `where` clause to delete a specific note.
where: 'id = ?',
// Pass the Note's id as a whereArg to prevent SQL injection.
whereArgs: [i],
);
}
}
setState(() {
for (int i = 0; i < isSelected.length; i++) {
if (isSelected[i] == true) {
noteTitle.removeAt(i);
noteContent.removeAt(i);
originalNoteTitle.removeAt(i);
originalNoteContent.removeAt(i);
isSelected.removeAt(i);
tileColor.removeAt(i);
}
}
});
}
@override
void initState() {
super.initState();
_initializeNotes();
}
Future<void> _initializeNotes() async {
if (!_isInitialized) {
await _retrieveNotes();
_isInitialized = true;
}
}
Future<void> _retrieveNotes() async {
var tempNoteTitleWait = [];
var tempNoteContentWait = [];
final database = await DatabaseProvider.database;
final List<Map<String, dynamic>> result = await selectNotesDB(database);
for (final row in result) {
tempNoteTitleWait.add(row['title']);
tempNoteContentWait.add(row['subtitle']);
}
setState(() {
noteTitle = List<String>.from(tempNoteTitleWait);
noteContent = List<String>.from(tempNoteContentWait);
originalNoteTitle = List<String>.from(tempNoteTitleWait);
originalNoteContent = List<String>.from(tempNoteContentWait);
});
}
事实证明,数据库和我正在使用的列表上一定有一些不同的索引,因此作为一半措施,我使用了 title[index] 代替,它似乎有效,我不确定为什么它不删除两个这样做时具有相同标题的注释,但它按预期工作,所以我猜这将是托德·霍华德“它就是有效”的一个实例。
Future deleteSelectedNotes() 异步 { 最终数据库=等待DatabaseProvider.database;
List<int> indicesToDelete = [];
// Remove the Note from the database.
for (int i = 0; i < isSelected.length; i++) {
if (isSelected[i] == true) {
await database.delete(
'Notes',
// Use a `where` clause to delete a specific note.
where: 'title = ?',
// Pass the Note's id as a whereArg to prevent SQL injection
whereArgs: [noteTitle[i]],
);
indicesToDelete.add(i);
}
}