Flutter使用sqflite时如何实现退出应用后收藏列表数据不丢失
问题原因
你当前的收藏列表favoriteWords仅存储在应用运行时的内存中,没有持久化到本地存储,所以应用重启后数据自然会丢失。主列表数据正常是因为你提前存入了sqflite数据库,收藏列表按照相同逻辑持久化即可,最简单的方案是给现有词条表加收藏状态字段,无需额外建表。
解决步骤
步骤1:修改Word实体类和数据库表结构
给Word类加isFavorite布尔字段,同时修改DbHelper里的建表语句,新增is_favorite INTEGER DEFAULT 0字段(sqlite无布尔类型,用0代表未收藏,1代表已收藏)。
示例代码:
// Word实体类新增字段 class Word { int id; String word; String description; bool isFavorite; // 新增字段,默认未收藏 Word({this.id, this.word, this.description, this.isFavorite = false}); // 转Map方法新增对应字段 Map<String, dynamic> toMap() { var map = <String, dynamic>{ 'id': id, 'word': word, 'description': description, 'is_favorite': isFavorite ? 1 : 0, }; return map; } // 从Map转Word对象新增对应字段解析 Word.fromMap(Map<String, dynamic> map) { id = map['id']; word = map['word']; description = map['description']; isFavorite = map['is_favorite'] == 1; } }
修改DbHelper的建表语句:
// 原有CREATE TABLE语句新增is_favorite字段 CREATE TABLE words (id INTEGER PRIMARY KEY AUTOINCREMENT, word TEXT, description TEXT, is_favorite INTEGER DEFAULT 0)
步骤2:DbHelper新增数据库操作方法
新增查询收藏列表、更新词条收藏状态的方法:
// 查询所有收藏的词条 Future<List<Word>> getFavoriteWords() async { var db = await this.db; var result = await db.query('words', where: 'is_favorite = ?', whereArgs: [1]); return result.map((map) => Word.fromMap(map)).toList(); } // 更新词条的收藏状态 Future<int> updateFavoriteStatus(int wordId, bool isFavorite) async { var db = await this.db; return await db.update( 'words', {'is_favorite': isFavorite ? 1 : 0}, where: 'id = ?', whereArgs: [wordId], ); }
步骤3:修改当前页面逻辑
3.1 初始化时加载收藏列表
修改initState方法,启动时同时加载主列表和收藏列表,顺便修复原有代码fwordCount未赋值导致收藏列表显示异常的问题:
@override void initState() { getWords(); getFavoriteWords(); // 新增这行 } // 新增获取收藏列表的方法 void getFavoriteWords() { var favFuture = dbHelper.getFavoriteWords(); favFuture.then((data) { setState(() { favoriteWords = data; fwordCount = data.length; }); }); }
3.2 收藏/取消收藏操作同步到数据库
修改主列表的收藏按钮点击逻辑:
ElevatedButton( onPressed: () async { // 改为异步方法 if (!favoriteWords.contains(words[position])) { // 先更新数据库状态 await dbHelper.updateFavoriteStatus(words[position].id, true); setState(() { favoriteWords.add(words[position]); fwordCount = favoriteWords.length; }); } }, // 其余样式代码保持不变 )
修改收藏列表的取消收藏按钮点击逻辑:
ElevatedButton( onPressed: () async { // 改为异步方法 // 先更新数据库状态 await dbHelper.updateFavoriteStatus(favoriteWords[index].id, false); setState(() { favoriteWords.removeAt(index); fwordCount = favoriteWords.length; }); }, // 其余样式代码保持不变 )
注意
如果是已上线应用需要处理数据库升级,在DbHelper的onUpgrade方法中执行ALTER TABLE words ADD COLUMN is_favorite INTEGER DEFAULT 0语句即可,本地测试直接卸载重装应用即可生效。
内容的提问来源于stack exchange,提问作者Aleyna Eser
相关产品推荐
相关产品推荐

