SQLite/SQFlite 更新在 Flutter 应用程序中不起作用
SQLite/ SQFlite updating is not working in a Flutter app
我正在使用 Flutter 和 Dart 编程语言构建应用程序。我使用 SQLite 作为本地数据库。现在我正在开发一个功能,当 ListView 的一个项目被点击时,我将数据传递到一个新的表单页面。但是更新数据不起作用。
以下是我的数据库助手class。注意updateNote方法
class DatabaseHelper {
static DatabaseHelper _databaseHelper;
Database _database;
String noteTable = 'note_table';
String colId = 'id';
String colTitle = 'title';
String colDescription = 'description';
String colPriority = 'priority';
String colDate = 'date';
DatabaseHelper._createInstance();
factory DatabaseHelper() {
if (_databaseHelper == null) {
_databaseHelper = DatabaseHelper._createInstance();
}
return _databaseHelper;
}
Future<Database> get database async {
if (_database == null) {
_database = await initializeDatabase();
}
return _database;
}
Future<Database> initializeDatabase() async {
Directory directory = await getApplicationDocumentsDirectory();
String path = directory.path + 'notes.db';
var notesDatabase = await openDatabase(path, version: 1, onCreate: _createDB);
return notesDatabase;
}
void _createDB(Database db, int newVersion) async {
await db.execute('CREATE TABLE $noteTable($colId INTEGER PRIMARY KEY AUTOINCREMENT, $colTitle TEXT, $colDescription TEXT, $colPriority INTEGER, $colDate TEXT)');
}
Future<List<Map<String, dynamic>>> getNoteMapList() async {
Database db = await this.database;
return await db.query(noteTable, orderBy: '$colPriority ASC');
}
Future<int> updateNote(Note note) async {
var db = await this.database;
return await db.update(noteTable, note.toMap(), where: '$colId = ?', whereArgs: [note.id]);
}
//there are other methods hidden here
}
我有一个小部件 class,它使用以下代码显示 ListView
class NoteList extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _NoteListState();
}
}
class _NoteListState extends State<NoteList> {
List<Note> _notes = [];
int _count = 0;
DatabaseHelper _databaseHelper = DatabaseHelper();
_NoteListState() {
getNotes();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Notes"),),
body: Container(
child: getListView(context),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
navigateToNoteForm("Add Note");
},
),
);
}
Widget getListView(BuildContext context) {
return ListView.builder(
itemCount: _count,
itemBuilder: (context, index) {
return ListTile(
leading: CircleAvatar(
backgroundColor: _notes[index].priority == 1? Colors.yellow: Colors.red,
child: Icon(_notes[index].priority == 1 ? Icons.arrow_right : Icons.add),
),
title: Text(_notes[index].title),
subtitle: Text(_notes[index].date),
trailing: Icon(Icons.delete),
onTap: () {
navigateToNoteForm("Edit Note", _notes[index]);
},
);
});
}
void navigateToNoteForm(String pageTitle, [Note note]) async {
bool result = await Navigator.push(context, MaterialPageRoute(builder: (context) {
return NoteForm(pageTitle, note);
}));
if (result) {
getNotes();
}
}
void getNotes() {
List<Note> notes = List<Note>();
Future<List<Map<String, dynamic>>> notesFuture = _databaseHelper.getNoteMapList();
notesFuture.then((notesMap) {
debugPrint("Total notes found in the database ${notesMap.length}");
notesMap.forEach((map) {
notes.add(Note.fromMapObject(map));
});
setState(() {
_notes = notes;
_count = notes.length;
});
});
}
}
如您所见,当单击 ListView 的一个项目时,我将数据传递给下一个小部件 NoteForm。
这是我的 NoteForm class 的实现。
class NoteForm extends StatefulWidget {
String _title = "";
Note _note = null;
NoteForm(String title, [Note note]) {
this._title = title;
this._note = note;
}
@override
State<StatefulWidget> createState() {
return _NoteFormState(this._title, this._note);
}
}
class _NoteFormState extends State<NoteForm> {
double _minimumPadding = 15.0;
var _priorities = [ 1, 2 ];
var _titleController = TextEditingController();
var _descriptionController = TextEditingController();
var _dateController = TextEditingController();
DatabaseHelper _databaseHelper = DatabaseHelper();
var _selectedPriority = 1;
String _title;
Note _note;
_NoteFormState(String title, [Note note]) {
this._title = title;
this._note = note;
if (this._note != null && this._note.id != null) {
_titleController.text = this._note.title;
_descriptionController.text = this._note.description;
_dateController.text = this._note.date;
_selectedPriority = this._note.priority;
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(this._title),),
body: Builder(
builder: (scaffoldContext) => Form(
child: Column(
children: <Widget>[
Container(
child: Padding(
padding: EdgeInsets.all(_minimumPadding),
child: TextFormField(
controller: _titleController,
decoration: InputDecoration(
labelText: "Title",
hintText: "Enter title"
),
),
),
),
Container(
child: Padding(
padding: EdgeInsets.all(_minimumPadding),
child: TextFormField(
controller: _descriptionController,
decoration: InputDecoration(
labelText: "Description",
hintText: "Enter description"
),
),
)
),
Container(
child: Padding(
padding: EdgeInsets.all(_minimumPadding),
child: TextFormField(
controller: _dateController,
decoration: InputDecoration(
labelText: "Date",
hintText: "Enter date"
),
),
),
),
Container(
child: Padding(
padding: EdgeInsets.all(_minimumPadding),
child: DropdownButton<int>(
value: _selectedPriority,
items: _priorities.map((dropdownItem) {
return DropdownMenuItem<int>(
value: dropdownItem,
child: Text(dropdownItem == 1? "Low": "High"),
);
}).toList(),
onChanged: (int newSelectedValue) {
setState(() {
_selectedPriority = newSelectedValue;
});
},
),
),
),
Container(
child: Padding(
padding: EdgeInsets.all(_minimumPadding),
child: RaisedButton(
child: Text(
"Save"
),
onPressed: () {
_save(scaffoldContext);
},
),
),
)
],
),
),
)
);
}
void _save(BuildContext context) async {
Note note = Note();
note.title = _titleController.text;
note.description = _descriptionController.text;
note.date = _dateController.text;
note.priority = _selectedPriority;
if (widget._note != null && widget._note.id!=null) {
//update
_databaseHelper.updateNote(note);
debugPrint("Note title is ${note.title}");
debugPrint("Note description is ${note.description}");
debugPrint("Note date is ${note.date}");
debugPrint("Note priority is ${note.priority}");
debugPrint("Note has been updated.");
this.showSnackBar(context, "Note has been updated.");
} else {
//create
_databaseHelper.insertNote(note);
debugPrint("Note has been created.");
this.showSnackBar(context, "Note has been added.");
}
closeForm(context);
}
void showSnackBar(BuildContext context, String message) {
var snackBar = SnackBar(
content: Text(message),
action: SnackBarAction(
label: "UNDO",
onPressed: () {
},
),
);
Scaffold.of(context).showSnackBar(snackBar);
}
void closeForm(BuildContext context) {
Navigator.pop(context, true);
}
}
当我更新笔记时,它没有更新。列表视图仍然显示相同的数据。我的代码有什么问题,我该如何解决?
当你打电话给 _databaseHelper.updateNote(note);
我相信你应该等待这个所以 await _databaseHelper.updateNote(note);
因为它 return 是未来所以现在你不是在等待你的数据至 return。您还有一些其他功能 return 期货。
也许你需要等待或未来,你在哪里打电话
也在 _databaseHelper.updateNote 中打印
你可以看到哪个先出现
void _save(BuildContext context) async {
Note note = Note();
note.title = _titleController.text;
note.description = _descriptionController.text;
note.date = _dateController.text;
note.priority = _selectedPriority;
if (widget._note != null && widget._note.id!=null) {
//update
await _databaseHelper.updateNote(note);
debugPrint("Note title is ${note.title}");
debugPrint("Note description is ${note.description}");
debugPrint("Note date is ${note.date}");
debugPrint("Note priority is ${note.priority}");
debugPrint("Note has been updated.");
this.showSnackBar(context, "Note has been updated.");
} else {
//create
await _databaseHelper.insertNote(note);
debugPrint("Note has been created.");
this.showSnackBar(context, "Note has been added.");
}
closeForm(context);
}
我发现了问题。这是我的代码。看看下面的片段。
Note note = Note();
note.title = _titleController.text;
note.description = _descriptionController.text;
note.date = _dateController.text;
note.priority = _selectedPriority;
我没有分配 id 值。因此该 id 始终为 null 以进行更新。感谢您的帮助。
我正在使用 Flutter 和 Dart 编程语言构建应用程序。我使用 SQLite 作为本地数据库。现在我正在开发一个功能,当 ListView 的一个项目被点击时,我将数据传递到一个新的表单页面。但是更新数据不起作用。
以下是我的数据库助手class。注意updateNote方法
class DatabaseHelper {
static DatabaseHelper _databaseHelper;
Database _database;
String noteTable = 'note_table';
String colId = 'id';
String colTitle = 'title';
String colDescription = 'description';
String colPriority = 'priority';
String colDate = 'date';
DatabaseHelper._createInstance();
factory DatabaseHelper() {
if (_databaseHelper == null) {
_databaseHelper = DatabaseHelper._createInstance();
}
return _databaseHelper;
}
Future<Database> get database async {
if (_database == null) {
_database = await initializeDatabase();
}
return _database;
}
Future<Database> initializeDatabase() async {
Directory directory = await getApplicationDocumentsDirectory();
String path = directory.path + 'notes.db';
var notesDatabase = await openDatabase(path, version: 1, onCreate: _createDB);
return notesDatabase;
}
void _createDB(Database db, int newVersion) async {
await db.execute('CREATE TABLE $noteTable($colId INTEGER PRIMARY KEY AUTOINCREMENT, $colTitle TEXT, $colDescription TEXT, $colPriority INTEGER, $colDate TEXT)');
}
Future<List<Map<String, dynamic>>> getNoteMapList() async {
Database db = await this.database;
return await db.query(noteTable, orderBy: '$colPriority ASC');
}
Future<int> updateNote(Note note) async {
var db = await this.database;
return await db.update(noteTable, note.toMap(), where: '$colId = ?', whereArgs: [note.id]);
}
//there are other methods hidden here
}
我有一个小部件 class,它使用以下代码显示 ListView
class NoteList extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _NoteListState();
}
}
class _NoteListState extends State<NoteList> {
List<Note> _notes = [];
int _count = 0;
DatabaseHelper _databaseHelper = DatabaseHelper();
_NoteListState() {
getNotes();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Notes"),),
body: Container(
child: getListView(context),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
navigateToNoteForm("Add Note");
},
),
);
}
Widget getListView(BuildContext context) {
return ListView.builder(
itemCount: _count,
itemBuilder: (context, index) {
return ListTile(
leading: CircleAvatar(
backgroundColor: _notes[index].priority == 1? Colors.yellow: Colors.red,
child: Icon(_notes[index].priority == 1 ? Icons.arrow_right : Icons.add),
),
title: Text(_notes[index].title),
subtitle: Text(_notes[index].date),
trailing: Icon(Icons.delete),
onTap: () {
navigateToNoteForm("Edit Note", _notes[index]);
},
);
});
}
void navigateToNoteForm(String pageTitle, [Note note]) async {
bool result = await Navigator.push(context, MaterialPageRoute(builder: (context) {
return NoteForm(pageTitle, note);
}));
if (result) {
getNotes();
}
}
void getNotes() {
List<Note> notes = List<Note>();
Future<List<Map<String, dynamic>>> notesFuture = _databaseHelper.getNoteMapList();
notesFuture.then((notesMap) {
debugPrint("Total notes found in the database ${notesMap.length}");
notesMap.forEach((map) {
notes.add(Note.fromMapObject(map));
});
setState(() {
_notes = notes;
_count = notes.length;
});
});
}
}
如您所见,当单击 ListView 的一个项目时,我将数据传递给下一个小部件 NoteForm。
这是我的 NoteForm class 的实现。
class NoteForm extends StatefulWidget {
String _title = "";
Note _note = null;
NoteForm(String title, [Note note]) {
this._title = title;
this._note = note;
}
@override
State<StatefulWidget> createState() {
return _NoteFormState(this._title, this._note);
}
}
class _NoteFormState extends State<NoteForm> {
double _minimumPadding = 15.0;
var _priorities = [ 1, 2 ];
var _titleController = TextEditingController();
var _descriptionController = TextEditingController();
var _dateController = TextEditingController();
DatabaseHelper _databaseHelper = DatabaseHelper();
var _selectedPriority = 1;
String _title;
Note _note;
_NoteFormState(String title, [Note note]) {
this._title = title;
this._note = note;
if (this._note != null && this._note.id != null) {
_titleController.text = this._note.title;
_descriptionController.text = this._note.description;
_dateController.text = this._note.date;
_selectedPriority = this._note.priority;
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(this._title),),
body: Builder(
builder: (scaffoldContext) => Form(
child: Column(
children: <Widget>[
Container(
child: Padding(
padding: EdgeInsets.all(_minimumPadding),
child: TextFormField(
controller: _titleController,
decoration: InputDecoration(
labelText: "Title",
hintText: "Enter title"
),
),
),
),
Container(
child: Padding(
padding: EdgeInsets.all(_minimumPadding),
child: TextFormField(
controller: _descriptionController,
decoration: InputDecoration(
labelText: "Description",
hintText: "Enter description"
),
),
)
),
Container(
child: Padding(
padding: EdgeInsets.all(_minimumPadding),
child: TextFormField(
controller: _dateController,
decoration: InputDecoration(
labelText: "Date",
hintText: "Enter date"
),
),
),
),
Container(
child: Padding(
padding: EdgeInsets.all(_minimumPadding),
child: DropdownButton<int>(
value: _selectedPriority,
items: _priorities.map((dropdownItem) {
return DropdownMenuItem<int>(
value: dropdownItem,
child: Text(dropdownItem == 1? "Low": "High"),
);
}).toList(),
onChanged: (int newSelectedValue) {
setState(() {
_selectedPriority = newSelectedValue;
});
},
),
),
),
Container(
child: Padding(
padding: EdgeInsets.all(_minimumPadding),
child: RaisedButton(
child: Text(
"Save"
),
onPressed: () {
_save(scaffoldContext);
},
),
),
)
],
),
),
)
);
}
void _save(BuildContext context) async {
Note note = Note();
note.title = _titleController.text;
note.description = _descriptionController.text;
note.date = _dateController.text;
note.priority = _selectedPriority;
if (widget._note != null && widget._note.id!=null) {
//update
_databaseHelper.updateNote(note);
debugPrint("Note title is ${note.title}");
debugPrint("Note description is ${note.description}");
debugPrint("Note date is ${note.date}");
debugPrint("Note priority is ${note.priority}");
debugPrint("Note has been updated.");
this.showSnackBar(context, "Note has been updated.");
} else {
//create
_databaseHelper.insertNote(note);
debugPrint("Note has been created.");
this.showSnackBar(context, "Note has been added.");
}
closeForm(context);
}
void showSnackBar(BuildContext context, String message) {
var snackBar = SnackBar(
content: Text(message),
action: SnackBarAction(
label: "UNDO",
onPressed: () {
},
),
);
Scaffold.of(context).showSnackBar(snackBar);
}
void closeForm(BuildContext context) {
Navigator.pop(context, true);
}
}
当我更新笔记时,它没有更新。列表视图仍然显示相同的数据。我的代码有什么问题,我该如何解决?
当你打电话给 _databaseHelper.updateNote(note);
我相信你应该等待这个所以 await _databaseHelper.updateNote(note);
因为它 return 是未来所以现在你不是在等待你的数据至 return。您还有一些其他功能 return 期货。
也许你需要等待或未来,你在哪里打电话
也在 _databaseHelper.updateNote 中打印 你可以看到哪个先出现
void _save(BuildContext context) async {
Note note = Note();
note.title = _titleController.text;
note.description = _descriptionController.text;
note.date = _dateController.text;
note.priority = _selectedPriority;
if (widget._note != null && widget._note.id!=null) {
//update
await _databaseHelper.updateNote(note);
debugPrint("Note title is ${note.title}");
debugPrint("Note description is ${note.description}");
debugPrint("Note date is ${note.date}");
debugPrint("Note priority is ${note.priority}");
debugPrint("Note has been updated.");
this.showSnackBar(context, "Note has been updated.");
} else {
//create
await _databaseHelper.insertNote(note);
debugPrint("Note has been created.");
this.showSnackBar(context, "Note has been added.");
}
closeForm(context);
}
我发现了问题。这是我的代码。看看下面的片段。
Note note = Note();
note.title = _titleController.text;
note.description = _descriptionController.text;
note.date = _dateController.text;
note.priority = _selectedPriority;
我没有分配 id 值。因此该 id 始终为 null 以进行更新。感谢您的帮助。