Flutter中SQLite数据无法映射到Reminder列表,APP无法显示求助
问题原因与解决方案
核心问题
你直接将Day/Activity枚举的toString()结果(格式如Day.monday)和TimeOfDay的toString()结果(格式如TimeOfDay(hour:8, minute:0))存入数据库,读取时却试图直接将字符串强制转换为对应类型,这会触发类型转换异常,无法生成有效的Reminder列表。
修复步骤
1. 修正数据存储格式
存储枚举时只保留枚举值名称(去掉前缀),存储TimeOfDay时使用标准化的时间字符串格式:
void addReminder(Day day, TimeOfDay time, Activity activity) async { final db = await _getDatabase(); final newReminder = Reminder(day: day, targetTime: time, activity: activity); try { // 提取枚举值名称(如"monday"而非"Day.monday") final dayStr = day.toString().split('.').last; final activityStr = activity.toString().split('.').last; // 将TimeOfDay转为"HH:mm"格式字符串 final timeStr = '${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}'; await db.rawInsert( 'INSERT INTO userReminders(day, targetTime, activity) VALUES(?, ?, ?)', [dayStr, timeStr, activityStr] ); state = [newReminder, ...state]; } catch (e) { print('Error inserting reminder: $e'); } }
2. 实现字符串到目标类型的转换函数
取消注释并完善转换逻辑:
// 字符串转Day枚举 Day dayFromString(String value) { return Day.values.firstWhere( (e) => e.toString().split('.').last == value, orElse: () => Day.monday, // 可选:设置默认值避免无匹配项报错 ); } // 字符串转Activity枚举 Activity activityFromString(String value) { return Activity.values.firstWhere( (e) => e.toString().split('.').last == value, orElse: () => Activity.wakeUp, // 可选:设置默认值 ); } // "HH:mm"格式字符串转TimeOfDay TimeOfDay timeStringToTimeOfDay(String timeStr) { final parts = timeStr.split(':'); return TimeOfDay(hour: int.parse(parts[0]), minute: int.parse(parts[1])); }
3. 修正数据读取逻辑
在loadReminders中调用转换函数,将数据库字符串转为对应类型:
Future<void> loadReminders() async { final db = await _getDatabase(); final data = await db.rawQuery('SELECT * FROM userReminders'); print(data); final reminders = data.map((e) => Reminder( day: dayFromString(e['day'] as String), targetTime: timeStringToTimeOfDay(e['targetTime'] as String), activity: activityFromString(e['activity'] as String), )).toList(); print(data.isEmpty); state = reminders; }
4. 额外说明
- 若数据库中已有旧格式数据,需清空数据库或编写迁移逻辑转换旧数据,否则读取旧数据时仍会报错。
- 使用参数化查询(
?占位符)替代字符串拼接,可避免SQL注入风险与字符串转义问题。
内容的提问来源于stack exchange,提问作者Bhavya Bedi
相关产品推荐
相关产品推荐

